欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

mysql主从数据库同步和字符集问题

程序员文章站 2022-05-02 18:24:12
...

1.mysql主从数据库同步问题 在使用mysql 5.0 主从数据库同步时遇到问题一些问题: 在主从数据库同步时,我们可能会选择哪些数据库要求同步,而那些数据库忽视,这两个功能是靠/etc/my.cnf文件中的两个键名 binlog_do_db 和 binlog_ignore_db 来实现的 binlog

1.mysql主从数据库同步问题

在使用mysql 5.0 主从数据库同步时遇到问题一些问题:
在主从数据库同步时,我们可能会选择哪些数据库要求同步,而那些数据库忽视,这两个功能是靠/etc/my.cnf文件中的两个键名 binlog_do_db 和 binlog_ignore_db 来实现的

binlog_do_db = 填写需要同步的数据库,多个数据库则用‘,’隔开

binlog_ignore_db = 填写不需同步的数据库,多个数据库用 ‘,’隔开

主数据库读取键值,可选择生成数据库日志文件。从服务器根据主服务器日志文件来更新自己的数据库

理论上这些都是可行的,然而实际实现中会遇到一些问题,问题如下:

从终端用 mysql -u -p 连接mysql数据库,主服务器执行数据库操作,在binlog_do_db范围内的数据库都会做日志记录,使用mysql提供的api函数用程序连接数据库执行sql语句缺不写入日志

几经周转测试,终于发现将binlog_ignore_db去掉,而且是连键名一起注释掉,这时候主从数据库同步方可成功,API函数进行的数据库操作可以写入日志了

这不知是官方bug,还是自己哪方面配置数据库错误。解决方案目前为止只限于此。



2.mysql 字符集设置

2.1终端访问:

通常终端访问只需在/etc/my.cnf中将default-charcter-set=utf8就不会出现乱码

2.2程序连接:

先看mysql字符集问题

数据库链接命令行中输入
show variables like 'char%';
得到以下结果
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 | 客户端字符集
| character_set_connection | utf8 | 连接字符集
| character_set_database | utf8 | 数据库字符集
| character_set_filesystem | binary |
| character_set_results | utf8 | 取得结果字符集
| character_set_server | utf8 | 服务器字符集
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.28 sec)

这个就是字符集表了

问题1:向默认字符集为utf8的数据表插入utf8数据前没有设置连接字符集,查询时设置字符集为utf8,导致的查询乱码。

1. 在插入的时候根据mysql服务的默认设置,character_set_client、character_set_connection和character_set_results均为latin1;所以在插入的时候,程序会把utf8字符集当成latin1(这一步不会转换,只是取数据),那么存储过程中数据会经过以下变换 latin1->latin1=>utf8的字符集转换过程,这一过程每个插入的汉字会经历程序到动态库;所以字符都会从原来的3个字节(程序utf8)在最后一步(latin1=>utf8)变成6个字节保存。

2. 查询时的结果将经过utf8=>utf8的字符集转换过程,将保存的6个字节原封不动返回,产生乱码

mysql主从数据库同步和字符集问题

图1

问题2: 向默认字符集为latin1的数据表插入utf8编码的数据前设置了连接字符集为utf8,取出数据出错

插入时根据连接字符集设置,character_set_client、character_set_connection和character_set_results均为utf8;

插入数据将经过utf8=>utf8=>latin1的字符集转换,若原始数据中含有/u0000~/u00ff范围以外的Unicode字符,会因为无法在latin1字符集中表示而被转换为“?”(0x3F)符号,以后查询时不管连接字符集设置如何都无法恢复其内容了。

mysql主从数据库同步和字符集问题

图2


3. mysql API PHP C

一般页面的PHP程序运行时间较短,在连接到数据库后用set names语句设置一次连接字符即可。但当使用长连接时,请注意保持通畅并在端来连接后再次用set names设置连接字符集。

问题1:
为什么有时候我们用终端登录的时候就不是乱码,但是用程序进行sql操作的时候就出现乱码了呢。
answer:因为程序链接的时候用的是动态链接库连接数据库的,而终端用的mysql_client自己安装的程序,这两个字符集可能会不相同。
问题2:
为什么程序运行有一段时间后就开始出现乱码了,插入与取出数据都是乱码了。
answer:connection有一个时间,超时就会重新连接 ,有两种设置方法
3.1 执行sql语句 set names 'utf8' 2
3.2 mysql_options(ledMysql, MYSQL_SET_CHARSET_NAME, "utf8");
第一种方法只是暂时有效,第二种方法再每次重连的时候都会设置字符集为utf8


使用mysql api时初始化数据库句柄后马上用 mysql_option设定MYSQL_SET_CHARASET_NAME属性为utf8,这样就不需要使用set names语句指定连接字符集。mysql_ping重新断开连接时也会吧连接字符重置为utf8,不需每次重连都set names
mysql带来的问题主要是字符集的问题。其实有一种更绝的方法就是在安装数据库的时候只保留utf8字符集那不管怎么连接都不会出现乱码了。


ATTENTION:

用程序连接数据库的时候调用的是动态链接库libmysqlclient.so or libmysqlclient.a

my.cnf 中的default_character_set 设置只影响在终端这种用mysql命令连接服务器时连接字符集,不会对使用libmysqlclient库连接mysql的应用程序产生任何作用。


4. 编译问题

./configure --prefix=/usr/local/mysql --sysconfdir=/etc --localstatedir=/var/lib/mysql --enable-local-infile --enable-assembler --with-charset=utf8 --with-big-tables --with-plugin-partition --with-plugin-federated

如果是非编译版本,安装的时候请注意使用,否则可能会安装到错误的位置

/usr/local/mysql/bin/mysqld_install --basedir=/usr/local/mysql --ldata=/var/lib/mysql

一般情况下都是不能正常链接数据库,错误提示一般为:

ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

其实网上大家问的最多的都是整个问题,说什么链接不到mysqld.sock,其实大家不妨看看mysql的错误日志就明白怎么回事,我这里的错误日志是在

/var/lib/mysql/*.err 你会发现mysql只所以不能启动,是因为/var/lib/mysql的权限不允许mysql服务访问,英文mysql默认是调用mysql用户来启动服务的,好了,既然知道是什么原因找到不能启动,那就简单了。我们只要

chown -R mysql:mysql /var/lib/mysql 就行,如果还是启动不了,再慢慢调试权限,反正一般启动不了都是权限的问题。

如果大家还是不能启动不了的话,那就用我的比较繁琐的权限的设置,反正我每次都是这么做的,一般不会有问题,见下:


chown -R root /usr/local/mysql
chgrp -R mysql /usr/local/mysql
chown -R root /usr/local/mysql/bin
chgrp -R mysql /usr/local/mysql/bin
chgrp -R mysql /var/lib/mysql
chmod 777 /var/lib/mysql
chown -R root /var/lib/mysql/mysql
chgrp -R mysql /var/lib/mysql/mysql
chmod 777 /var/lib/mysql/mysql
chown -R root /var/lib/mysql/mysql/*
chgrp -R mysql /var/lib/mysql/mysql/*
chmod 777 /var/lib/mysql/mysql/*
chmod 777 /usr/local/mysql/lib/mysql/libmysqlclient.a