ホームページ >データベース >mysql チュートリアル >mysql主从数据库同步和字符集问题
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个字节原封不动返回,产生乱码。
图1
问题2: 向默认字符集为latin1的数据表插入utf8编码的数据前设置了连接字符集为utf8,取出数据出错
插入时根据连接字符集设置,character_set_client、character_set_connection和character_set_results均为utf8;
插入数据将经过utf8=>utf8=>latin1的字符集转换,若原始数据中含有/u0000~/u00ff范围以外的Unicode字符,会因为无法在latin1字符集中表示而被转换为“?”(0x3F)符号,以后查询时不管连接字符集设置如何都无法恢复其内容了。
图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字符集那不管怎么连接都不会出现乱码了。
用程序连接数据库的时候调用的是动态链接库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