禁止修改varchar到int|[运维规范]

在MySQL更改数据类型前一定要特别小心,分析一下是不是可行,另外在更改前,需要先进行备份,备份,备份!!!

环境描述

表结构:

CREATE TABLE `t_mobile` (
 `mobile_no` varchar(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

写入数据:

root@zhishutang:mysql3306.sock [zst]>insert into t_mobile(mobile_no) values('13501245755'),('18800108001'),('13996000001');

确认数据无误:

root@zhishutang:mysql3306.sock [zst]>select * from t_mobile;
+-------------+
| mobile_no |
+-------------+
| 13501245755 |
| 18800108001 |
| 13996000001 |
+-------------+
3 rows in set (0.00 sec)

溢出

修改数类型:

root@zhishutang:mysql3306.sock [zst]>alter table t_mobile change mobile_no mobile_no int;
Query OK, 3 rows affected, 3 warnings (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 3

查看警告:

root@zhishutang:mysql3306.sock [zst]>show warnings;
+---------+------+----------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------+
| Warning | 1264 | Out of range value for column 'mobile_no' at row 1 |
| Warning | 1264 | Out of range value for column 'mobile_no' at row 2 |
| Warning | 1264 | Out of range value for column 'mobile_no' at row 3 |
+---------+------+----------------------------------------------------+
3 rows in set (0.00 sec)

到这里实质就可以宣布,死定了。数据已溢出。

查看数据:

root@zhishutang:mysql3306.sock [zst]>select * from t_mobile;
+------------+
| mobile_no |
+------------+
| 2147483647 |
| 2147483647 |
| 2147483647 |
+------------+
3 rows in set (0.00 sec)

这里真是的男人哭吧,哭吧, … 如果是线上环境,想死的心估计大家都有了,不是简单的哭了。如果没有备份,这么重要一例数据没了,有可能意为着项目也有可能受到严重的影响。

这时也不要心存幻想在改回去就好,来看一下操作,请死心!!!

root@zhishutang:mysql3306.sock [zst]>alter table t_mobile change mobile_no mobile_no varchar(11);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0

root@zhishutang:mysql3306.sock [zst]>select * from t_mobile;
+------------+
| mobile_no |
+------------+
| 2147483647 |
| 2147483647 |
| 2147483647 |
+------------+
3 rows in set (0.00 sec)

结论

  • 生产环境更数据类型明确提出: 不允许varchar 改成int.
  • 更改数据前一定要做好备份,无论是update,delete,或是数据类型更改。

操作Tips: 如保备份一列数据?

select pk , 修改的列 from tb where 条件 ;

用命令行记录也可以,用outfile处理也行。

恢复可以用awk反向生成update语句:
cat bak.txt |awk ‘{print “update tb set 修改列名=“ 2,”where pk=1”;”}

大概这样生成。 在执行恢复即可。

 

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

我猜你一定达不到要求的《MySQL安全策略》

导读

除了MySQL自身的账号密码安全管理,系统层面、应用层面的安全策略你注意到了吗?

数据是企业核心资产,数据对企业而言是最重要的工作之一。稍有不慎,极有可能发生数据无意泄露,甚至被黑客恶意窃取的风险。每年业界都会传出几起大事件,某知名或不知名的公司被脱裤(拖库的谐音,意思是整个数据库被黑客盗取)之类的。

从数据安全上也可以分为外网安全及内部操作安全,下面分别讨论一下。

内部操作安全策略

1. 是否回收DBA全部权限

试想,如果DBA没权限了,日常DB运维的活,以及紧急故障处理,该怎么实施呢?因此,建议在没有成熟的自动化运维平台前,不应该粗暴的回收DBA的太多权限,否则可能会导致工作效率降低的,甚至DBA有一种不被信任的负面情绪。

2. MySQL层安全策略

  • 业务帐号最多只可以通过内网远程登录,而不能通过公网远程连接。
  • 增加运维平台账号,该账号允许从专用的管理平台服务器远程连接。当然了,要对管理平台部署所在服务器做好安全措施以及必要的安全审计策略。
  • 建议启用数据库审计功能。这需要使用MySQL企业版,或者Percona/MariaDB分支版本,MySQL社区版本不支持该功能。
  • 启用 safe-update 选项,避免没有 WHERE 条件的全表数据被修改;
  • 在应用中尽量不直接DELETE删除数据,而是设置一个标志位就好了。需要真正删除时,交由DBA先备份后再物理删除,避免误操作删除全部数据。
  • 还可以采用触发器来做一些辅助功能,比如防止黑客恶意篡改数据。

3. MySQL账号权限规则

  • 业务帐号,权限最小化,坚决不允许DROP、TRUNCATE权限。
  • 业务账号默认只授予普通的DML所需权限,也就是select、update、insert、delete、execute等几个权限,其余不给。
  • MySQL初始化后,先行删除无用账号,删除匿名test数据库
mysql> delete from mysql.user where user!='root' or host!='localhost'; flush privileges;

mysql> drop database test;
  • 创建备份专用账号,只有SELECT权限,且只允许本机可登入。
  • 设置MySQL账号的密码安全策略,包括长度、复杂性。

4. 关于数据备份

记住,做好数据全量备份是系统崩溃无法修复时的最后一概救命稻草
备份数据还可以用来做数据审计或是用于数据仓库的数据源拉取之用
一般来说,备份策略是这样的:每天一次全备,并且定期对binlog做增备,或者直接利用binlog server机制将binlog传输到其他远程主机上。有了全备+binlog,就可以按需恢复到任何时间点。
特别提醒:当采用xtrabackup的流式备份时,考虑采用加密传输,避免备份数据被恶意截取。

外网安全策略

事实上,操作系统安及应用安全要比数据库自身的安全策略更重要。同理,应用程序及其所在的服务器端的系统安全也很重要,很多数据安全事件,都是通过代码漏洞入侵到应用服务器,再去探测数据库,最后成功拖库。

1. 操作系统安全建议

  • 运行MySQL的Linux必须只运行在内部网络,不允许直接对公网暴露,实在有需要从公网连接的话,再通过跳板机做端口转发,并且如上面所述,要严格限制数据库账号权限级别。
  • 系统账号都改成基于ssh key认证,不允许远程密码登入,且ssh key的算法、长度有要求以确保相对安全。这样就没有密码丢失的风险,除非个人的私钥被盗。
  • 进一步的话,甚至可以对全部服务器启用PAM认证,做到账号的统一管理,也更方便、安全。
  • 关闭不必要的系统服务,只开必须的进程,例如 mysqld、sshd、networking、crond、syslogd 等服务,其它的都关闭。
  • 禁止root账号远程登录。
  • 禁止用root账号启动mysqld等普通业务服务进程。
  • sshd服务的端口号建议修改成10000以上。
  • 在不影响性能的前提下,尽可能启用对MySQL服务端口的防火墙策略(高并发时,采用iptables可能影响性能,建议改用ip route策略)。
  • GRUB必须设置密码,物理服务器的Idrac/imm/ilo等账号默认密码也要修改。
  • 每个需要登入系统的员工,都使用每个人私有帐号,而不是使用公共账号。
  • 应该启用系统层的操作审计,记录所有ssh日志,或利bash记录相应的操作命令并发送到远程服务器,然后进行相应的安全审计,及时发现不安全操作。
  • 正确设置MySQL及其他数据库服务相关目录权限,不要全是755,一般750就够了。
  • 可以考虑部署堡垒机,所有连接远程服务器都需要先通过堡垒机,堡垒机上就可以实现所有操作记录以及审计功能了。
  • 脚本加密对安全性提升其实没太大帮助。对有经验的黑客来说,只要有系统登入权限,就可以通过提权等方式轻松获得root。

2. 应用安全建议

  • 禁用web server的autoindex配置。
  • 从制度层面,杜绝员工将代码上传到外部github上,因为很可能存在内部IP、账号密码泄露的风险,真的要上传必须先经过安全审核。
  • 尽量不要在公网上使用开源的cms、blog、论坛等系统,除非做过代码安全审计,或者事先做好安全策略。这类系统一般都是黑客重点研究对象,很容易被搞;
  • 在web server层,可以用一些安全模块,比如nginx的WAF模块;
  • 在app server层,可以做好代码安全审计、安全扫描,防止XSS攻击、CSRF攻击、SQL注入、文件上传攻击、绕过cookie检测等安全漏洞;
  • 应用程序中涉及账号密码的地方例如JDBC连接串配置,尽量把明文密码采用加密方式存储,再利用内部私有的解密工具进行反解密后再使用。或者可以让应用程序先用中间账号连接proxy层,再由proxy连接MySQL,避免应用层直连MySQL;

最后我们想说,任何高明的安全策略,都不如内部员工的安全意识来的重要。以前发生过一起案例,公司内有位员工的PC不慎中毒,结果导致内网数据被盗。

安全无小事,每个人都应铭记于心。在数据安全面前,可以适当牺牲一些便利性,当然也不能太过,否则可能得不偿失。

 

From:

云DB

MySQL binlog后面的编号最大是多大?

    在上课中讲到MySQL的binlog是mysql-bin.000001,有细心的学习提到,是不是这个达到mysql-bin.999999后数据库的binlog就要重新开始了?
对于这个问题一时间也被问住了,只是隐约记得这个可以出现大于999999,这次也来细致的研究一下,顺便Mark一下。
MySQL在启动时会扫一下binlog文件,找到sequence后最大的一个,然后产生下个文件,根据这个原理,我们可以先测试一下当有了mysql-bin.999999 后,数据库会不会产生mysql-bin.000001或是mysql-bin.1000000。

测试一:

把mysqld关掉,到日志目录:

touch mysql-bin.999999
[root@zst1 17:26:28 /data/mysql/mysql3307/logs]
#touch mysql-bin.999999

[root@zst1 17:26:37 /data/mysql/mysql3307/logs]
#ls -lh
total 12K
-rw-r----- 1 mysql mysql 923 May 22 22:16 mysql-bin.000001
-rw-r----- 1 mysql mysql 660 May 22 22:28 mysql-bin.000002
-rw-r--r-- 1 root root 0 May 24 17:26 mysql-bin.999999
-rw-r----- 1 mysql mysql 88 May 22 22:19 mysql-bin.index

[root@zst1 17:26:40 /data/mysql/mysql3307/logs]
#chown mysql:mysql *
[root@zst1 17:26:48 /data/mysql/mysql3307/logs]
#/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3307/my3307.cnf &
[root@zst1 17:27:17 /data/mysql/mysql3307/logs]
#ls -lh
total 76K
-rw-r----- 1 mysql mysql 923 May 22 22:16 mysql-bin.000001
-rw-r----- 1 mysql mysql 660 May 24 17:27 mysql-bin.000002
-rw-r----- 1 mysql mysql 194 May 24 17:27 mysql-bin.1000000
-rw-r--r-- 1 mysql mysql 0 May 24 17:26 mysql-bin.999999
-rw-r----- 1 mysql mysql 133 May 24 17:27 mysql-bin.index

启动mysqld
show master status 确认:

root@zhishutang:mysql3307.sock [(none)]>show master status;
+-------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.1000000 | 194 | | | 61beeb3d-2a88-11e7-9db9-080027f7e774:3-4 |
+-------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

可以看到,并没有挂掉,也没重新从mysql-bin.000001开始。

对于这个问题,我们在来挖一下,具体是什么?
教学使用的版本是mysql-5.7.18下载相应的源码看看 : sql/binlog.cc 实际找到:
从这里可以看到:
zhishutang.com
if (max_found == MAX_LOG_UNIQUE_FN_EXT)
当找到的数是定义的最大数时,就退出,再找一下MAX_LOG_UNIQUE_FN_EXT定义:

#define MAX_LOG_UNIQUE_FN_EXT 0x7FFFFFFF

root@zhishutang:mysql3307.sock [(none)]>select conv('7FFFFFFF',16,10);
+------------------------+
| conv('7FFFFFFF',16,10) |
+------------------------+
| 2147483647 |
+------------------------+
1 row in set (0.00 sec)

现在看到是最大值是: pow(2,31)-1
我们来测试几个场景:

测试二: 测试当达到mysql-bin.2147483647 再进行flush logs;MySQL的反应。

touch mysql-bin.2147483640

启动后给的警告:

2017-05-24T09:57:43.081308Z 0 [Warning] Next log extension: 2147483641. Remaining log filename extensions: 6. Please consider archiving some logs.
2017-05-24T09:57:43.081436Z 0 [Note] InnoDB: Buffer pool(s) load completed at 170524 17:57:43
2017-05-24T09:57:43.090250Z 0 [Warning] Next log extension: 2147483641. Remaining log filename extensions: 6. Please consider archiving some logs.

root@localhost:mysql3307.sock [(none)]>flush logs;
Query OK, 0 rows affected (0.01 sec)

root@localhost:mysql3307.sock [(none)]>show master status;
+----------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.2147483647 | 194 | | | 61beeb3d-2a88-11e7-9db9-080027f7e774:3-4 |
+----------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

进行切换超限一下试试

root@localhost:mysql3307.sock [(none)]>flush logs;
ERROR 1598 (HY000): Binary logging not possible. Message: Either disk is full or file system is read only while rotating the binlog. Aborting the server.
root@localhost:mysql3307.sock [(none)]>flush logs;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql3307.sock' (111)
ERROR:
Can't connect to the server

mysqld 直接退出…

报错日志:

2017-05-24T09:59:08.207040Z 3 [Warning] Next log extension: 2147483642. Remaining log filename extensions: 5. Please consider archiving some logs.
2017-05-24T09:59:09.970075Z 3 [Warning] Next log extension: 2147483643. Remaining log filename extensions: 4. Please consider archiving some logs.
2017-05-24T09:59:10.882140Z 3 [Warning] Next log extension: 2147483644. Remaining log filename extensions: 3. Please consider archiving some logs.
2017-05-24T09:59:12.050605Z 3 [Warning] Next log extension: 2147483645. Remaining log filename extensions: 2. Please consider archiving some logs.
2017-05-24T09:59:14.090312Z 3 [Warning] Next log extension: 2147483646. Remaining log filename extensions: 1. Please consider archiving some logs.
2017-05-24T09:59:26.483618Z 3 [Warning] Next log extension: 2147483647. Remaining log filename extensions: 0. Please consider archiving some logs.
2017-05-24T09:59:34.894426Z 3 [ERROR] Log filename extension number exhausted: 2147483647. Please fix this by archiving old logs and updating the index files.
2017-05-24T09:59:34.894441Z 3 [ERROR] Can't generate a unique log-filename /data/mysql/mysql3307/logs/mysql-bin.(1-999)

2017-05-24T09:59:34.894668Z 3 [ERROR] /usr/local/mysql/bin/mysqld: Binary logging not possible. Message: Either disk is full or file system is read only while rotating the binlog. Aborting the server.

看样是想产生mysql-bin.(1-999) 这样的文件。 再进行进行下面的测试。

测试三: 测试Binlog达到最大值后,能不能重新开始。

确保mysql-bin.000001不存在到999都不存在

root@localhost:mysql3307.sock [(none)]>show master status;
+----------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.2147483646 | 154 | | | 61beeb3d-2a88-11e7-9db9-080027f7e774:3-4 |
+----------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

root@localhost:mysql3307.sock [(none)]>flush logs;
Query OK, 0 rows affected (0.01 sec)

root@localhost:mysql3307.sock [(none)]>show master status;
+----------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.2147483647 | 154 | | | 61beeb3d-2a88-11e7-9db9-080027f7e774:3-4 |
+----------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

root@localhost:mysql3307.sock [(none)]>flush logs;
ERROR 1598 (HY000): Binary logging not possible. Message: Either disk is full or file system is read only while rotating the binlog. Aborting the server.
root@localhost:mysql3307.sock [(none)]>show master status;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql3307.sock' (111)
ERROR:
Can't connect to the server

一样退出。并没有进行日志的轮换使用。

结论:
1. mysql binlog的最大sequence是:pow(2,31)-1 = 2147483647
2. 当binlog接近这个值是小于1000开始向error log中写入警告
3. binlog的sequence达到最大值时,不管有没有mysql-bin.000001类似这样的文件,mysqld都是退出。
4. 在mysql产生binlog时会读取当前日件文目录下的log-bin的base name获取下一个日志文件的后面的Seq。 所以日志目录下文件太多,会影响MySQL的启动及日志切换。 这里也有一个大的隐患运行中给放一个较大的日志文件,在下次日志文件切换时有可能很快就接近于最大值,造成mysqld crash退出。
5. 一定要监控error log的输出。并足够重视。

 

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

Innodb表select查询顺序不对?

今天知数堂一个学生反馈说在优化课中老师讲Innodb是以主键排序存储,读取的时间以主键为顺序读取,但发现个例外,如下:

CREATE TABLE zst_t1 (

uid int(10) NOT NULL AUTO_INCREMENT,

id int(11) NOT NULL,

PRIMARY KEY (uid),

KEY idx_id (id)

) ENGINE=InnoDB;’

写入数据:

INSERT INTO zst_t1 VALUES (1,1),(12,1),(22,1),(23,1),(33,1),(2,2),(3,2),(10,2),(11,2),(4,4),(13,4),(14,4);

执行查询:

select * from zst_t1;

为什么这个顺序是乱的,不按顺序排列呢?难道Innodb表并不是全按主键存储?

使用innodb_ruby这个工具查看一下存储结构什么样

看样子存储还是按主键排序存储的。没毛病。

再来看一下该表的索引:

看到这里应该明白了怎么会事了吧,原来这个查询是走的索引覆盖,没有在进行回表读取原数据。另外,也在此说明,Innodb二索索引包含了主键存储。

来继续证明一下:

看到using index 吧,表示这个查询利用索引查询出来结果,不用读取原表。

那么我们给造一个通过主键读取数据操作:

select * from zst_t1 use index(primary);

select * from zst_t1 use index(primary);  #确认一下。

总结:

这个其实就是一个索引包含的查询案例。 如果静下来思考一下,也许很快就明白了。也不用这样去查问题。

技术在于折腾,多搞搞就明白了:)。

centos 6下innodb_ruby安装

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

innodb_ruby是jeremycole的一个用于分析Innodb相关结构的一个程序,也是非常方便我们研究Innodb的结构工具。所以这里做一个介绍。

jeremycole github里的分享的项目都很优秀,这里就直接推荐一下他的github: https://github.com/jeremycole

innodb_ruby依赖ruby>=1.9.3的版本。 Centos默认yum版本比较低。需要手工编译,建议从ruby-china的镜象(https://ruby-china.org/wiki/ruby-mirror)上下载:

#wget https://cache.ruby-china.org/pub/ruby/ruby-1.9.3-p551.tar.gz

安装前需要把依赖包先安装上:

#yum -y install zlib-devel curl-devel openssl-devel httpd-devel apr-devel apr-util-devel

如果系统里没装mysql请把mysql-devel这个包也装一下。

 

tar zxvf ruby-1.9.3-p551.tar.gz

cd ruby-1.9.3-p551

./configure

make

make install

 

完成Ruby安装后,就可以安装innodb_ruby

gem install innodb_ruby

等待提示成功后,就可以开始innodb_ruby之旅。

参考帮助: https://github.com/jeremycole/innodb_ruby/wiki

Innodb好玩的开始了。

特别提示: 注意上面的命令需要在datadir下执行。玩的开心。

mysqld_multi关闭不了MySQL处理Tips

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

在启用MySQL多实例中,很多环境会选择使用mysqld_multi管理多实例,但不幸的是从MySQL 5.6 后,
mysqld_mutli不能把MySQL关掉了。

对于这个问题的处理办法,首先确认:

mysqladmin -h127.0.0.1 -P3307 -umdev -p shutdown
or
mysqladmin -S /tmp/mysql3307.sock -umdev -p shutdown

工作没问题。

创建用户:

create user ‘mdev’@’localhost’ identified by ‘mdev4admin’;
grant shutdown on *.* to ‘mdev’@’localhost’;

很幸运mysqld_multi是一个Perl脚本,找原因也方便,有兴趣参考后面的文档。
处理办法:

  1. 修改mysqld_mutli 把
    my $com= join ' ', 'my_print_defaults ', @defaults_options, $group;
    替换为:
    my $com= join ' ', 'my_print_defaults -s', @defaults_options, $group;
  2. 调用mysqld_multi传入password
    mysqld_multi stop 3307 --password=mdev4admin

如果需要更多信息,可以加入QQ群:529671799  下载。

MySQL Binlog Server

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

MySQL Binlog Server:是利用某个工具,把线上活跃的库的日志拉取到本地进行备份。在MySQL 5.6以后,可以利用mysqlbinlog这个命令去把远程机器的日志备份到本地目录,从而达到增量或是日志安全方面的备份。

做好MySQL日志的备份,是数据安全的一个重要保证。以前通过写程序来实现,从MySQL 5.6出现以后,DBA同步有福了,不用写程序了。
下面说一下binlog Server怎么构建。
利用mysql 5.6的mysqlbinlog命令,可以把远程的binlog完全镜象一份放到本地,方法如下:

/usr/local/mysql/bin/mysqlbinlog -R --raw --host=192.168.11.100 --user='repl' --password='repl4slave' --stop-never mysql-bin.000001&

解释一下:
-R –read-from-remote-server 表示从远程机器上读取binlog,要确保远程mysql存储,需要提供–host, –user, –password参数
–raw 以binlog格式存储日志,方便后期使用
–stop-never 一直连接到远程的server上读取日志,直接到远程的server关闭后才会退出。或是被pkill掉
mysql-bin.0000001 这个日志名表示从那个日志开始读取

如果需要启动多个binlog server,需要给binlog server指定server-id(默认是65535),可以利用 –stop-never-slave-server-id变更

启动一个server-id为1的binlog server:

/usr/local/mysql/bin/mysqlbinlog -R --raw --host=192.168.11.100 --user='repl' --password='repl4slave' --stop-never --stop-never-slave-server-id=1 mysql-bin.000003&

启动一个server-id为2的binlog server:

/usr/local/mysql/bin/mysqlbinlog -R --raw --host=192.168.11.100 --user='repl' --password='repl4slave' --stop-never --stop-never-slave-server-id=2 mysql-bin.000003&

思考:
这种binlog server怎么关闭才算安全呢?

[TIPS]安装数据库提示无法解析机器名处理

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

在做MySQL初始化时,如果机器的名不能进行反解会出现以下错误:

WARNING: The host 'node2' could not be looked up with resolveip.
This probably means that your libc libraries are not 100 % compatible
with this binary MySQL version. The MySQL daemon, mysqld, should work
normally with the exception that host name resolving will not work.
This means that you should use IP addresses instead of hostnames
when specifying MySQL privileges !
#/usr/local/mysql/bin/resolveip node2

/usr/local/mysql/bin/resolveip: Unable to find hostid for ‘node2’: host not found

处理过程如下

1. 查看机器的名

#hostanme

node2

2. 查看/etc/hosts文件

#cat /etc/hosts

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

可见/etc/hosts中无相应的机器名

添ip(本机的ip) 到机器的对应到/etc/hosts中:

最终/etc/hosts内容如下:

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
10.10.60.148 node2

3.使用resolveip确认是否ok

#/usr/local/mysql/bin/resolveip node2

IP address of node2 is 10.10.60.148

4. 在次运行初始化程序

cd /usr/local/mysql
./script/mysql_db_install

Good luck!

TIPS:MySQL 改库名操作

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

MySQL在5.1引入了一个rename database操作,但在MySQL5.1.23后又不支持这个命令。可以说是一个实验性的功能,没有在生产中支持过(mysql-5.1 release在mysql-5.1.30),那么生产中我们有时为了追求完美需要改一下库名。怎么操作呢?
这里提供一个变通的方法。
1. 创建出新库名:

mysql>create database db_v2;
  1. 生成rename语句,从olddb里迁移,我这里olddb里sbtest;
mysql>select concat("rename table ",table_schema,".",table_name," to db_v2.",table_name,";") into outfile '/tmp/rename_to_db_v2.sql' from information_schema.tables where table_schema='sbtest';

3.执行生成的sql

mysql>source /tmp/rename_to_db_v2.sql

就这么简单可以搞定了。
Good luck!

MySQL整型数据溢出的处理策略

作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.

今天接到一个朋友电话说是觉的数据库被别人更改了,出现数据不对的问题 。经过很久的排查是数据类型溢出了(发生问题的版本是MySQL 5.1)。后来通过给朋友那边把MySQL 5.1升级到MySQL 5.5去解决这个问题。 这也让我有兴趣去了解一下MySQL不同版本数据类型溢出的处理机制。

先看一下MySQL支持的整型数及大小,存储空间:

Type Storage Minimum Value Maximum Value 存储大小
  (Bytes) (Signed/Unsigned) (Signed/Unsigned) byte
TINYINT 1 -128 127 1 byte
    0 255  
SMALLINT 2 -32768 32767 2 bytes
    0 65535  
MEDIUMINT 3 -8388608 8388607 3 bytes
    0 16777215  
INT 4 -2147483648 2147483647 4 bytes
    0 4294967295  
BIGINT 8 -9223372036854775808 9223372036854775807 8 bytes
    0 18446744073709551615  

另外请记着mysql的数据处理会转成bigint处理,所以这里就用bigint几个测试:

SELECT CAST(0 AS UNSIGNED) - 1;

SELECT 9223372036854775807 + 1;

MySQL 5.1 下:

mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 AS UNSIGNED) - 1 |
+-------------------------+
|    18446744073709551615 |
+-------------------------+
1 row in set (0.01 sec)

mysql> SELECT 9223372036854775807 + 1;
+-------------------------+
| 9223372036854775807 + 1 |
+-------------------------+
|    -9223372036854775808 |
+-------------------------+
1 row in set (0.01 sec)

MySQL 5.5, 5.6, 5.7下:

mysql> SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
mysql> 
mysql> 
mysql> 
mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'

所在处理这类数据是一定要小心溢出(如早期有做弊冲Q币就是利用这个方法处理)

这个问题有可能会出现积分消息,积分相加, 或是一些钱相关的业务中出现, 主库5.1 ,从库MySQL 5.5情况也会出现不同步的问题。
建议:这类业务系统尽可能的升级到MySQL 5.5后版本 

更多详情参考: http://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html