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

WBOY
发布: 2016-06-07 15:53:16
原创
978 人浏览过

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


来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!