MySQL的binlog日志

binlog 基本认识
MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。

一般来说开启二进制日志大概会有1%的性能损耗(参见MySQL官方中文手册 5.1.24版)。二进制有两个最重要的使用场景:
其一:MySQL Replication在Master端开启binlog,Mster把它的二进制日志传递给slaves来达到master-slave数据一致的目的。
其二:自然就是数据恢复了,通过使用mysqlbinlog工具来使恢复数据。

二进制日志包括两类文件:二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件,二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句)语句事件。
一、开启binlog日志:
vi编辑打开mysql配置文件
# vi /usr/local/mysql/etc/my.cnf
在[mysqld] 区块
设置/添加 log-bin=mysql-bin 确认是打开状态(值 mysql-bin 是日志的基本名或前缀名);

重启mysqld服务使配置生效
# pkill mysqld
# /usr/local/mysql/bin/mysqld_safe –user=mysql &
二、也可登录mysql服务器,通过mysql的变量配置表,查看二进制日志是否已开启 单词:variable[ˈvɛriəbəl] 变量

登录服务器
# /usr/local/mysql/bin/mysql -uroot -p123456

mysql> show variables like ‘log_%’;
+—————————————-+—————————————+
| Variable_name | Value |
+—————————————-+—————————————+
| log_bin | ON | ——> ON表示已经开启binlog日志
| log_bin_basename | /usr/local/mysql/data/mysql-bin |
| log_bin_index | /usr/local/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| log_error | /usr/local/mysql/data/martin.err |
| log_output | FILE |
| log_queries_not_using_indexes | OFF |
| log_slave_updates | OFF |
| log_slow_admin_statements | OFF |
| log_slow_slave_statements | OFF |
| log_throttle_queries_not_using_indexes | 0 |
| log_warnings | 1 |
+—————————————-+—————————————+

三、常用binlog日志操作命令
1.查看所有binlog日志列表
mysql> show master logs;

2.查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;

3.刷新log日志,自此刻开始产生一个新编号的binlog日志文件
mysql> flush logs;
注:每当mysqld服务重启时,会自动执行此命令,刷新binlog日志;在mysqldump备份数据时加 -F 选项也会刷新binlog日志;

4.重置(清空)所有binlog日志
mysql> reset master;
四、查看某个binlog日志内容,常用有两种方式:

1.使用mysqlbinlog自带查看命令法:
注: binlog是二进制文件,普通文件查看器cat more vi等都无法打开,必须使用自带的 mysqlbinlog 命令查看
binlog日志与数据库文件在同目录中(我的环境配置安装是选择在/usr/local/mysql/data中)
在MySQL5.5以下版本使用mysqlbinlog命令时如果报错,就加上 “–no-defaults”选项

# /usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/data/mysql-bin.000013
下面截取一个片段分析:

…………………………………………………………………….
# at 552
#131128 17:50:46 server id 1 end_log_pos 665 Query thread_id=11 exec_time=0 error_code=0 —->执行时间:17:50:46;pos点:665
SET TIMESTAMP=1385632246/*!*/;
update zyyshop.stu set name=’李四’ where id=4 —->执行的SQL
/*!*/;
# at 665
#131128 17:50:46 server id 1 end_log_pos 692 Xid = 1454 —->执行时间:17:50:46;pos点:692
…………………………………………………………………….

注: server id 1 数据库主机的服务号;
end_log_pos 665 pos点
thread_id=11 线程号
2.上面这种办法读取出binlog日志的全文内容较多,不容易分辨查看pos点信息,这里介绍一种更为方便的查询命令:

mysql> show binlog events [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count];

选项解析:
IN ‘log_name’ 指定要查询的binlog文件名(不指定就是第一个binlog文件)
FROM pos 指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
LIMIT [offset,] 偏移量(不指定就是0)
row_count 查询总条数(不指定就是所有行)

截取部分查询结果:
*************************** 20. row ***************************
Log_name: mysql-bin.000021 ———————————————-> 查询的binlog日志文件名
Pos: 11197 ———————————————————-> pos起始点:
Event_type: Query ———————————————————-> 事件类型:Query
Server_id: 1 ————————————————————–> 标识是由哪台服务器执行的
End_log_pos: 11308 ———————————————————-> pos结束点:11308(即:下行的pos起始点)
Info: use `zyyshop`; INSERT INTO `team2` VALUES (0,345,’asdf8er5′) —> 执行的sql语句
*************************** 21. row ***************************
Log_name: mysql-bin.000021
Pos: 11308 ———————————————————-> pos起始点:11308(即:上行的pos结束点)
Event_type: Query
Server_id: 1
End_log_pos: 11417
Info: use `zyyshop`; /*!40000 ALTER TABLE `team2` ENABLE KEYS */
*************************** 22. row ***************************
Log_name: mysql-bin.000021
Pos: 11417
Event_type: Query
Server_id: 1
End_log_pos: 11510
Info: use `zyyshop`; DROP TABLE IF EXISTS `type`

这条语句可以将指定的binlog日志文件,分成有效事件行的方式返回,并可使用limit指定pos点的起始偏移,查询条数;

A.查询第一个(最早)的binlog日志:
mysql> show binlog events\G;

B.指定查询 mysql-bin.000021 这个文件:
mysql> show binlog events in ‘mysql-bin.000021’\G;

C.指定查询 mysql-bin.000021 这个文件,从pos点:8224开始查起:
mysql> show binlog events in ‘mysql-bin.000021’ from 8224\G;

D.指定查询 mysql-bin.000021 这个文件,从pos点:8224开始查起,查询10条
mysql> show binlog events in ‘mysql-bin.000021’ from 8224 limit 10\G;

E.指定查询 mysql-bin.000021 这个文件,从pos点:8224开始查起,偏移2行,查询10条
mysql> show binlog events in ‘mysql-bin.000021’ from 8224 limit 2,10\G;
五、恢复binlog日志实验(zyyshop是数据库)
1.假设现在是凌晨4:00,我的计划任务开始执行一次完整的数据库备份:

将zyyshop数据库备份到 /root/BAK.zyyshop.sql 文件中:
# /usr/local/mysql/bin/mysqldump -uroot -p123456 -lF –log-error=/root/myDump.err -B zyyshop > /root/BAK.zyyshop.sql
……

大约过了若干分钟,备份完成了,我不用担心数据丢失了,因为我有备份了,嘎嘎~~~

由于我使用了-F选项,当备份工作刚开始时系统会刷新log日志,产生新的binlog日志来记录备份之后的数据库“增删改”操作,查看一下:
mysql> show master status;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000023 | 120 | | |
+——————+———-+————–+——————+
也就是说, mysql-bin.000023 是用来记录4:00之后对数据库的所有“增删改”操作。
2.早9:00上班了,业务的需求会对数据库进行各种“增删改”操作~~~~~~~
@ 比如:创建一个学生表并插入、修改了数据等等:
CREATE TABLE IF NOT EXISTS `tt` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(16) NOT NULL,
`sex` enum(‘m’,’w’) NOT NULL DEFAULT ‘m’,
`age` tinyint(3) unsigned NOT NULL,
`classid` char(6) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
导入实验数据
mysql> insert into zyyshop.tt(`name`,`sex`,`age`,`classid`) values(‘yiyi’,’w’,20,’cls1′),(‘xiaoer’,’m’,22,’cls3′),(‘zhangsan’,’w’,21,’cls5′),(‘lisi’,’m’,20,’cls4′),(‘wangwu’,’w’,26,’cls6′);
查看数据
mysql> select * from zyyshop.tt;
+—-+———-+—–+—–+———+
| id | name | sex | age | classid |
+—-+———-+—–+—–+———+
| 1 | yiyi | w | 20 | cls1 |
| 2 | xiaoer | m | 22 | cls3 |
| 3 | zhangsan | w | 21 | cls5 |
| 4 | lisi | m | 20 | cls4 |
| 5 | wangwu | w | 26 | cls6 |
+—-+———-+—–+—–+———+
中午时分又执行了修改数据操作
mysql> update zyyshop.tt set name=’李四’ where id=4;
mysql> update zyyshop.tt set name=’小二’ where id=2;

修改后的结果:
mysql> select * from zyyshop.tt;
+—-+———-+—–+—–+———+
| id | name | sex | age | classid |
+—-+———-+—–+—–+———+
| 1 | yiyi | w | 20 | cls1 |
| 2 | 小二 | m | 22 | cls3 |
| 3 | zhangsan | w | 21 | cls5 |
| 4 | 李四 | m | 20 | cls4 |
| 5 | wangwu | w | 26 | cls6 |
+—-+———-+—–+—–+———+
假设此时是下午18:00,莫名地执行了一条悲催的SQL语句,整个数据库都没了:
mysql> drop database zyyshop;
3.此刻杯具了,别慌!先仔细查看最后一个binlog日志,并记录下关键的pos点,到底是哪个pos点的操作导致了数据库的破坏(通常在最后几步);

备份一下最后一个binlog日志文件:
# ll /usr/local/mysql/data | grep mysql-bin
# cp -v /usr/local/mysql/data/mysql-bin.000023 /root/

此时执行一次刷新日志索引操作,重新开始新的binlog日志记录文件,理论说 mysql-bin.000023 这个文件不会再有后续写入了(便于我们分析原因及查找pos点),以后所有数据库操作都会写入到下一个日志文件;
mysql> flush logs;
mysql> show master status;

4.读取binlog日志,分析问题
方式一:使用mysqlbinlog读取binlog日志:
# /usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/data/mysql-bin.000023

方式二:登录服务器,并查看(推荐):
mysql> show binlog events in ‘mysql-bin.000023′;

以下为末尾片段:
+——————+——+————+———–+————-+————————————————————+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+——————+——+————+———–+————-+————————————————————+
| mysql-bin.000023 | 922 | Xid | 1 | 953 | COMMIT /* xid=3820 */ |
| mysql-bin.000023 | 953 | Query | 1 | 1038 | BEGIN |
| mysql-bin.000023 | 1038 | Query | 1 | 1164 | use `zyyshop`; update zyyshop.tt set name=’李四’ where id=4|
| mysql-bin.000023 | 1164 | Xid | 1 | 1195 | COMMIT /* xid=3822 */ |
| mysql-bin.000023 | 1195 | Query | 1 | 1280 | BEGIN |
| mysql-bin.000023 | 1280 | Query | 1 | 1406 | use `zyyshop`; update zyyshop.tt set name=’小二’ where id=2|
| mysql-bin.000023 | 1406 | Xid | 1 | 1437 | COMMIT /* xid=3823 */ |
| mysql-bin.000023 | 1437 | Query | 1 | 1538 | drop database zyyshop |
+——————+——+————+———–+————-+————————————————————+

通过分析,造成数据库破坏的pos点区间是介于 1437–1538 之间,只要恢复到1437前就可。
5.现在把凌晨备份的数据恢复:

# /usr/local/mysql/bin/mysql -uroot -p123456 -v < /root/BAK.zyyshop.sql;

注: 至此截至当日凌晨(4:00)前的备份数据都恢复了。
但今天一整天(4:00–18:00)的数据肿么办呢?就得从前文提到的 mysql-bin.000023 新日志做文章了……
6.从binlog日志恢复数据

恢复语法格式:
# mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库名

常用选项:
–start-position=953 起始pos点
–stop-position=1437 结束pos点
–start-datetime=”2013-11-29 13:18:54″ 起始时间点
–stop-datetime=”2013-11-29 13:21:53″ 结束时间点
–database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)

不常用选项:
-u –user=name Connect to the remote server as username.连接到远程主机的用户名
-p –password[=name] Password to connect to remote server.连接到远程主机的密码
-h –host=name Get the binlog from server.从远程主机上获取binlog日志
–read-from-remote-server Read binary logs from a MySQL server.从某个MySQL服务器上读取binlog日志

小结:实际是将读出的binlog日志内容,通过管道符传递给mysql命令。这些命令、文件尽量写成绝对路径;

A.完全恢复(本例不靠谱,因为最后那条 drop database zyyshop 也在日志里,必须想办法把这条破坏语句排除掉,做部分恢复)
# /usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/data/mysql-bin.000021 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop

B.指定pos结束点恢复(部分恢复):
@ –stop-position=953 pos结束点
注:此pos结束点介于“导入实验数据”与更新“name=’李四’”之间,这样可以恢复到更改“name=’李四’”之前的“导入测试数据”
# /usr/local/mysql/bin/mysqlbinlog –stop-position=953 –database=zyyshop /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop

在另一终端登录查看结果(成功恢复了):
mysql> select * from zyyshop.tt;
+—-+———-+—–+—–+———+
| id | name | sex | age | classid |
+—-+———-+—–+—–+———+
| 1 | yiyi | w | 20 | cls1 |
| 2 | xiaoer | m | 22 | cls3 |
| 3 | zhangsan | w | 21 | cls5 |
| 4 | lisi | m | 20 | cls4 |
| 5 | wangwu | w | 26 | cls6 |
+—-+———-+—–+—–+———+

C.指定pso点区间恢复(部分恢复):
更新 name=’李四’ 这条数据,日志区间是Pos[1038] –> End_log_pos[1164],按事务区间是:Pos[953] –> End_log_pos[1195];

更新 name=’小二’ 这条数据,日志区间是Pos[1280] –> End_log_pos[1406],按事务区间是:Pos[1195] –> End_log_pos[1437];

c1.单独恢复 name=’李四’ 这步操作,可这样:
# /usr/local/mysql/bin/mysqlbinlog –start-position=1038 –stop-position=1164 –database=zyyshop /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop

也可以按事务区间单独恢复,如下:
# /usr/local/mysql/bin/mysqlbinlog –start-position=953 –stop-position=1195 –database=zyyshop /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop
c2.单独恢复 name=’小二’ 这步操作,可这样:
# /usr/local/mysql/bin/mysqlbinlog –start-position=1280 –stop-position=1406 –database=zyyshop /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop

也可以按事务区间单独恢复,如下:
# /usr/local/mysql/bin/mysqlbinlog –start-position=1195 –stop-position=1437 –database=zyyshop /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop
c3.将 name=’李四’、name=’小二’ 多步操作一起恢复,需要按事务区间,可这样:
# /usr/local/mysql/bin/mysqlbinlog –start-position=953 –stop-position=1437 –database=zyyshop /usr/local/mysql/data/mysql-bin.000023 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop
D.在另一终端登录查看目前结果(两名称也恢复了):
mysql> select * from zyyshop.tt;
+—-+———-+—–+—–+———+
| id | name | sex | age | classid |
+—-+———-+—–+—–+———+
| 1 | yiyi | w | 20 | cls1 |
| 2 | 小二 | m | 22 | cls3 |
| 3 | zhangsan | w | 21 | cls5 |
| 4 | 李四 | m | 20 | cls4 |
| 5 | wangwu | w | 26 | cls6 |
+—-+———-+—–+—–+———+

E.也可指定时间区间恢复(部分恢复):除了用pos点的办法进行恢复,也可以通过指定时间区间进行恢复,按时间恢复需要用mysqlbinlog命令读取binlog日志内容,找时间节点。
比如,我把刚恢复的tt表删除掉,再用时间区间点恢复
mysql> drop table tt;

@ –start-datetime=”2013-11-29 13:18:54″ 起始时间点
@ –stop-datetime=”2013-11-29 13:21:53″ 结束时间点

# /usr/local/mysql/bin/mysqlbinlog –start-datetime=”2013-11-29 13:18:54″ –stop-datetime=”2013-11-29 13:21:53″ –database=zyyshop /usr/local/mysql/data/mysql-bin.000021 | /usr/local/mysql/bin/mysql -uroot -p123456 -v zyyshop

总结:所谓恢复,就是让mysql将保存在binlog日志中指定段落区间的sql语句逐个重新执行一次而已。

mysql5.7配置文件优化

[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
#支持符号链接,就是可以通过软连接的方式,管理其他目录的数据库,最好不要开启,当一个磁盘或分区空间不够时,可以开启该参数将数据存储到其他的磁盘或分区。
#http://blog.csdn.net/moxiaomomo/article/details/17092871
symbolic-links=0

########basic settings########
server-id = 11
port = 3306
user = mysql
#设置autocommit=0,则用户将一直处于某个事务中,直到执行一条commit提交或rollback语句才会结束当前事务重新开始一个新的事务。set autocommit=0的好处是在频繁开启事务的场景下,减少一次begin的交互。
autocommit = 1
#utf8mb4编码是utf8编码的超集,兼容utf8,并且能存储4字节的表情字符。
#采用utf8mb4编码的好处是:存储与获取数据的时候,不用再考虑表情字符的编码与解码问题。
character_set_server=utf8mb4
skip_name_resolve = 1
max_connections = 800
# 对于同一主机,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST。
max_connect_errors = 1000
#数据库隔离级别
transaction_isolation = READ-COMMITTED
#MySQL在完成某些join(连接)需求的时候,为了减少参与join的“被驱动表”的读取次数以提高性能,需要使用到join buffer来协助完成join操作当join buffer 太小,MySQL不会将该buffer存入磁盘文件而是先将join buffer中的结果与需求join的表进行操作,然后清空join buffer中的数据,继续将剩余的结果集写入次buffer中
join_buffer_size = 128M
tmp_table_size = 64M
tmpdir = /tmp
#该值设置过小将导致单个记录超过限制后写入数据库失败,且后续记录写入也将失败
max_allowed_packet = 64M
#mysql在关闭一个交互的连接之前所要等待的秒数
interactive_timeout = 1200
#mysql在关闭一个非交互的连接之前所要等待的秒数
wait_timeout = 600
#MySQL读入缓冲区的大小
read_buffer_size = 16M
#MySQL的随机读缓冲区大小
read_rnd_buffer_size = 8M
#MySQL的顺序读缓冲区大小
sort_buffer_size = 8M
########log settings########
log_error = /var/log/docker_log/mysql/error.log
#开启慢查询日志
slow_query_log = 1
#超出次设定值的SQL即被记录到慢查询日志
long_query_time = 6
slow_query_log_file = /var/log/docker_log/mysql/slow.log
#表示记录下没有使用索引的查询
log_queries_not_using_indexes = 1
#记录管理语句
log_slow_admin_statements = 1
#开启复制从库复制的慢查询的日志
log_slow_slave_statements = 1
#设置每分钟增长的没有使用索引查询的日志数量
log_throttle_queries_not_using_indexes = 10
expire_logs_days = 90
min_examined_row_limit = 100
########replication settings########
#将master.info和relay.info保存在表中
master_info_repository = TABLE
relay_log_info_repository = TABLE
log_bin = bin.log
#当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。设置为零是让系统自行决定
sync_binlog = 5
#开启全局事务ID,GTID能够保证让一个从服务器到其他的从服务器那里实现数据复制而且能够实现数据整合的
gtid_mode = on
#开启gtid,必须主从全开
enforce_gtid_consistency = 1
#从服务器的更新是否写入二进制日志
log_slave_updates = 1
#三种模式 STATEMENT(有可能主从数据不一致,日质量小)、ROW(产生大量二进制日志)、MIXED
binlog_format = mixed
#relay-log日志记录的是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后SQL线程会读取relay-log日志的内容并应用到从服务器
relay_log = /var/log/docker_log/mysql/relay.log
relay_log_recovery = 1
#开启简单gtid,开启此项会提升mysql执行恢复的性能
binlog_gtid_simple_recovery = 1
slave_skip_errors = ddl_exist_errors
########innodb settings########
#这个参数在一开始初始化时就要加入my.cnf里,如果已经创建了表,再修改,启动MySQL会报错。最好为8K
#innodb_page_size = 16K
innodb_page_size = 8K
#数据缓冲区buffer pool大小,建议使用物理内存的 75%
innodb_buffer_pool_size = 2G
#当buffer_pool的值较大的时候为1,较小的设置为8
innodb_buffer_pool_instances = 8
#运行时load缓冲池,快速预热缓冲池,将buffer pool的内容(文件页的索引)dump到文件中,然后快速load到buffer pool中。避免了数据库的预热过程,提高了应用访问的性能
innodb_buffer_pool_load_at_startup = 1
#运行时dump缓冲池
innodb_buffer_pool_dump_at_shutdown = 1
#在innodb中处理用户查询后,其结果在内存空间的缓冲池已经发生变化,但是还未记录到磁盘。这种页面称为脏页,将脏页记录到磁盘的过程称为刷脏
innodb_lru_scan_depth = 2000
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
#事务等待获取资源等待的最长时间,超过这个时间还未分配到资源则会返回应用失败,默认50s
innodb_lock_wait_timeout = 30
#日志组所在的路径,默认为data的home目录;
innodb_log_group_home_dir = /data/mysql/
#innodb_undo_directory = /data/mysql/undolog/
#这个参数控制着innodb数据文件及redo log的打开、刷写模式,http://blog.csdn.net/gua___gua/article/details/44916207
#innodb_flush_method = O_DIRECT-不经过系统缓存直接存入磁盘,
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_strict_mode = 1
#innodb独享表空间,有点很多,缺点会导致单个表文件过大
#innodb_file_per_table = 1
#undo日志回滚段 默认为128
innodb_undo_logs = 128
#传统机械硬盘建议使用,而对于固态硬盘可以关闭
#innodb_flush_neighbors = 1
innodb_log_file_size = 1G
innodb_log_buffer_size = 64M
#控制是否使用独立purge线程
innodb_purge_threads = 1
#改为ON时,允许单列索引最大达到3072。否则最大为767
innodb_large_prefix = 1
innodb_thread_concurrency = 8
#开启后会将所有的死锁记录到error_log中
innodb_print_all_deadlocks = 1
innodb_sort_buffer_size = 16M
########semi sync replication settings########
#半同步复制
plugin_load = “rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so”
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 5000
#表示转储每个bp instance LRU上最热的page的百分比。通过设置该参数可以减少转储的page数。
innodb_buffer_pool_dump_pct = 40
#刷脏的进程N-1
innodb_page_cleaners = 4
innodb_undo_log_truncate = 1
innodb_max_undo_log_size = 2G
#控制回收(收缩)undo log的频率.undo log空间在它的回滚段没有得到释放之前不会收缩,
innodb_purge_rseg_truncate_frequency = 128
log_timestamps=system
#该参数基于MySQL5.7 Group Replication组复制的,没有使用不要设置
#transaction_write_set_extraction=MURMUR32
#http://www.cnblogs.com/hzhida/archive/2012/08/08/2628826.html
show_compatibility_56=on

keepalived 配置项注解

一、配置项

global_defs {
notification_email {  #指定keepalived在发生切换时需要发送email到的对象,一行一个
sysadmin@fire.loc
}
notification_email_from Alexandre.Cassen@firewall.loc #指定发件人
smtp_server localhost #指定smtp服务器地址
smtp_connect_timeout 30 #指定smtp连接超时时间
router_id LVS_DEVEL #运行keepalived机器的一个标识
}
vrrp_sync_group VG_1{ #监控多个网段的实例
group {
inside_network #实例名
outside_network
}
notify_master /path/xx.sh #指定当切换到master时,执行的脚本
notify_backup /path/xx.sh #指定当切换到backup时,执行的脚本
notify_fault “path/xx.sh VG_1” #故障时执行的脚本
notify /path/xx.sh
smtp_alert #使用global_defs中提供的邮件地址和smtp服务器发送邮件通知
}

#因为Keepalived在转换状态时会依照状态来呼叫:
#当进入Master状态时会呼叫notify_master
#当进入Backup状态时会呼叫notify_backup
#当发现异常情况时进入Fault状态呼叫notify_fault
vrrp_instance inside_network {
state BACKUP #指定那个为master,那个为backup,如果设置了nopreempt这个值不起作用,主备考priority决


interface eth0 #设置实例绑定的网卡 VRRP心跳包从哪块网卡发出
dont_track_primary #忽略vrrp的interface错误(默认不设置)
track_interface{ #设置额外的监控,里面那个网卡出现问题都会切换
eth0
eth1
}
mcast_src_ip #发送多播包的地址,如果不设置默认使用绑定网卡的primary ip
garp_master_delay #在切换到master状态后,延迟进行gratuitous ARP请求
virtual_router_id 50 #VPID标记 相同VRID的LVS属于同一组,根据优先级选举出一个主
priority 99 #优先级,高优先级竞选为master
advert_int 10 #检查间隔,默认1秒 VRRP心跳包的发送周期,单位为s 组播信息发送间隔,两个节点设置必须一样(实际并不一定完全是10秒,测试结果是小于10秒的随机值)
nopreempt #设置为不抢占 注:这个配置只能设置在backup主机上,而且这个主机优先级要比另外一台高

首先nopreemt必须在state为BACKUP的节点上才生效(因为是BACKUP节点决定是否来成为MASTER的),其次要实现类似于关闭auto failback的功能需要将所有节点的state都设置为BACKUP,或者将master节点的priority设置的比BACKUP低。我个人推荐使用将所有节点的state都设置成BACKUP并且都加上nopreempt选项,这样就完成了关于autofailback功能,当想手动将某节点切换为MASTER时只需去掉该节点的nopreempt选项并且将priority改的比其他节点大,然后重新加载配置文件即可(等MASTER切过来之后再将配置文件改回去再reload一下)。
preempt_delay #抢占延时,默认5分钟
debug #debug级别
authentication { #设置认证
auth_type PASS #认证方式
auth_pass 111111 #认证密码(密码只识别前8位)
}
virtual_ipaddress { #设置vip
192.168.202.200
}
}
virtual_server 192.168.202.200 23 {
delay_loop 6 #健康检查时间间隔(实际并不一定完全是6秒,测试结果是小于6秒的随机值?)
lb_algo rr  #lvs调度算法rr|wrr|lc|wlc|lblc|sh|dh
lb_kind DR  #负载均衡转发规则NAT|DR|RUN
persistence_timeout 5 #会话保持时间
protocol TCP #使用的协议
persistence_granularity <NETMASK> #lvs会话保持粒度
virtualhost <string> #检查的web服务器的虚拟主机(host:头)
sorry_server<IPADDR> <port> #备用机,所有realserver失效后启用
real_server 192.168.200.5 23 {
weight 1 #默认为1,0为失效
inhibit_on_failure #在服务器健康检查失效时,将其设为0,而不是直接从ipvs中删除
notify_up <string> | <quoted-string> #在检测到server up后执行脚本
notify_down <string> | <quoted-string> #在检测到server down后执行脚本

TCP_CHECK {
connect_timeout 3 #连接超时时间
nb_get_retry 3 #重连次数
delay_before_retry 3 #重连间隔时间
connect_port 23  健康检查的端口的端口
bindto <ip>
}
HTTP_GET | SSL_GET{
url{ #检查url,可以指定多个
path /
digest <string> #检查后的摘要信息
status_code 200 #检查的返回状态码
}
connect_port <port>
bindto <IPADD>
connect_timeout 5
nb_get_retry 3
delay_before_retry 2
}

SMTP_CHECK{
host{
connect_ip <IP ADDRESS>
connect_port <port> #默认检查25端口
bindto <IP ADDRESS>
}
connect_timeout 5
retry 3
delay_before_retry 2
helo_name <string> | <quoted-string> #smtp helo请求命令参数,可选
}
MISC_CHECK{
misc_path <string> | <quoted-string> #外部脚本路径
misc_timeout #脚本执行超时时间
misc_dynamic #如设置该项,则退出状态码会用来动态调整服务器的权重,返回0 正常,不修改;返回1,

检查失败,权重改为0;返回2-255,正常,权重设置为:返回状态码-2
}
}

 

1、其他配置项说明

keepalived 的核心就是将IPVS配置成高可用,生成ipvs规则来完成负载均衡效果。

virtual server (虚拟服务)的定义:
virtual_server IP port       #定义虚拟主机IP地址及其端口
virtual_server fwmark int    #ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string  #将多个虚拟服务器定义成组,将组定义成虚拟服务
lb_algo{rr|wrr|lc|wlc|lblc|lblcr} #定义LVS的调度算法
lb_kind {NAT|DR|TUN}               #定义LVS的模型
presitence_timeout<INT>           #定义支持持久连接的时长
protocol TCP                       #规则所能支持的协议
sorry_server <IPADDR><PORT>       #如果所有real_server都出现故障了,利用此返回信息

 

二、术语

虚拟路由器

由一个Master路由器和多个Backup路由器组成。主机将虚拟路由器当作默认网关;

VRID

虚拟路由器的标识。有相同VRID的一组路由器构成一个虚拟路由器;

Master路由器

虚拟路由器中承担报文转发任务的路由器;

Backup路由器

Master路由器出现故障时,能够代替Master路由器工作的路由器;

虚拟IP 地址

虚拟路由器的IP 地址。一个虚拟路由器可以拥有一个或多个IP地址;

IP地址拥有者

接口IP地址与虚拟IP地址相同的路由器被称为IP地址拥有者;

虚拟MAC地址

一个虚拟路由器拥有一个虚拟MAC地址。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址;

优先级

VRRP根据优先级来确定虚拟路由器中每台路由器的地位;

非抢占方式

如果Backup路由器工作在非抢占方式下,则只要Master路由器没有出现故障Backup路由器即使随后被配置了更高的优先级也不会成为Master路由器;

抢占方式

如果Backup路由器工作在抢占方式下,当它收到VRRP报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的Master路由器的优先级高,就会主动抢占成为Master路由器;否则,将保持Backup状态.

 

三、高级使用

1、介绍

Keeaplived 主要有两种应用场景,一个是通过配置keepalived结合ipvs做到负载均衡(LVS+Keepalived)。另一个是通过自身健康检查、资源接管功能做高可用(双机热备),实现故障转移。

以下内容主要针对Keepalived+MySQL双主实现双机热备为根据,主要讲解keepalived的状态转换通知功能,利用此功能可有效加强对MySQL数据库监控。此文不再讲述Keepalived+MySQL双主部署过程,有需求者可参考以往博文:http://blog.jobbole.com/94643/

2、keepalived主要作用

keepalived采用VRRP(virtual router redundancy protocol),虚拟路由冗余协议,以软件的形式实现服务器热备功能。通常情况下是将两台linux服务器组成一个热备组(master-backup),同一时间热备组内只有一台主服务器(master)提供服务,同时master会虚拟出一个共用IP地址(VIP),这个VIP只存在master上并对外提供服务。如果keepalived检测到master宕机或服务故障,备服务器(backup)会自动接管VIP成为master,keepalived并将master从热备组移除,当master恢复后,会自动加入到热备组,默认再抢占成为master,起到故障转移功能。

3、工作在三层、四层和七层原理

Layer3:工作在三层时,keepalived会定期向热备组中的服务器发送一个ICMP数据包,来判断某台服务器是否故障,如果故障则将这台服务器从热备组移除。

Layer4:工作在四层时,keepalived以TCP端口的状态判断服务器是否故障,比如检测mysql 3306端口,如果故障则将这台服务器从热备组移除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
示例:
! Configuration File for keepalived
global_defs {
   notification_email {
     example@163.com
   }
   notification_email_from  example@example.com
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id MYSQL_HA
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 50
    nopreempt                   #当主down时,备接管,主恢复,不自动接管
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        ahth_pass 123
    }
    virtual_ipaddress {
        192.168.1.200          #虚拟IP地址
    }
}
virtual_server 192.168.1.200 3306 {        
    delay_loop 6
#    lb_algo rr 
#    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.1.201 3306 {       #监控本机3306端口
        weight 1
        notify_down /etc/keepalived/kill_keepalived.sh   #检测3306端口为down状态就执行此脚本(只有keepalived关闭,VIP才漂移 ) 
        TCP_CHECK {         #健康状态检测方式,可针对业务需求调整(TTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK)
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

Layer7:工作在七层时,keepalived根据用户设定的策略判断服务器上的程序是否正常运行,如果故障则将这台服务器从热备组移除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
示例:
! Configuration File for keepalived
global_defs {
   notification_email {
     example@163.com
   }
   notification_email_from  example@example.com
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id MYSQL_HA
}
vrrp_script check_nginx {
    script /etc/keepalived/check_nginx.sh    #检测脚本
    interval 2   #执行间隔时间
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 50
    nopreempt                   #当主down时,备接管,主恢复,不自动接管
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        ahth_pass 123
    }
    virtual_ipaddress {
        192.168.1.200          #虚拟IP地址
    }
    track_script {          #在实例中引用脚本
        check_nginx
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
脚本内容如下:
# cat /etc/keepalived/check_nginx.sh
Count1=`netstat -antp |grep -v grep |grep nginx |wc -l`
if [ $Count1 -eq 0 ]; then
    /usr/local/nginx/sbin/nginx
    sleep 2
    Count2=`netstat -antp |grep -v grep |grep nginx |wc -l`
    if [ $Count2 -eq 0 ]; then
        service keepalived stop
    else
        exit 0
    fi 
else
    exit 0
fi

 4、健康状态检测方式

4.1 HTTP服务状态检测

1
2
3
4
5
6
7
8
9
10
11
12
  HTTP_GET或SSL_GET {    
      url {
          path /index.html        #检测url,可写多个
          digest  24326582a86bee478bac72d5af25089e    #检测效验码
          #digest效验码获取方法:genhash -s IP -p 80 -u http://IP/index.html 
          status_code 200         #检测返回http状态码
      }
      connect_port 80 #连接端口
      connect_timeout 3  #连接超时时间
      nb_get_retry 3  #重试次数
      delay_before_retry 2 #连接间隔时间
   }

4.2 TCP端口状态检测(使用TCP端口服务基本上都可以使用)

1
2
3
4
5
6
  TCP_CHECK {    
      connect_port 80     #健康检测端口,默认为real_server后跟端口
      connect_timeout 5
      nb_get_retry 3
      delay_before_retry 3
  }

4.3 邮件服务器SMTP检测

1
2
3
4
5
6
7
8
9
10
  SMTP_CHECK {            #健康检测邮件服务器smtp    
      host {
          connect_ip
          connect_port
      }
      connect_timeout 5
      retry 2
      delay_before_retry 3
      hello_name "mail.domain.com"
  }

4.4 用户自定义脚本检测real_server服务状态

1
2
3
4
5
  MISC_CHECK {    
      misc_path /script.sh    #指定外部程序或脚本位置
      misc_timeout 3      #执行脚本超时时间
      !misc_dynamic       #不动态调整服务器权重(weight),如果启用将通过退出状态码动态调整real_server权重值
  }

5、状态转换通知功能

keepalived主配置邮件通知功能,默认当real_server宕机或者恢复时才会发出邮件。有时我们更想知道keepalived的主服务器故障切换后,VIP是否顺利漂移到备服务器,MySQL服务器是否正常?那写个监控脚本吧,可以,但没必要,因为keepalived具备状态检测功能,所以我们直接使用就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
主配置默认邮件通知配置模板如下:
global_defs           # Block id
    {
    notification_email    # To:
        {
        admin@example1.com
        ...
         }
    # From: from address that will be in header
    notification_email_from admin@example.com
    smtp_server 127.0.0.1   # IP
    smtp_connect_timeout 30 # integer, seconds
    router_id my_hostname   # string identifying the machine,
                            # (doesn't have to be hostname).
    enable_traps            # enable SNMP traps
        }

 5.1 实例状态通知

a) notify_master :节点变为master时执行

b) notify_backup : 节点变为backup时执行

c) notify_fault  : 节点变为故障时执行

5.2 虚拟服务器检测通知

a) notify_up   : 虚拟服务器up时执行

b) notify_down  : 虚拟服务器down时执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
示例:
    ! Configuration File for keepalived
    global_defs {
       notification_email {
         example@163.com
       }
       notification_email_from example@example.com 
       smtp_server 127.0.0.1
       smtp_connect_timeout 30
       router_id MYSQL_HA
    }
    vrrp_instance VI_1 {
        state BACKUP
        interface eth1
        virtual_router_id 50
        nopreempt           #当主down时,备接管,主恢复,不自动接管
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            ahth_pass 123
        }
        virtual_ipaddress {
            192.168.1.200
        }
            notify_master /etc/keepalived/to_master.sh
            notify_backup /etc/keepalived/to_backup.sh
            notify_fault /etc/keepalived/to_fault.sh
    }
    virtual_server 192.168.1.200 3306 {
        delay_loop 6
        persistence_timeout 50
        protocol TCP
        real_server 192.168.1.201 3306 {
            weight 1
            notify_up /etc/keepalived/mysql_up.sh
            notify_down /etc/keepalived/mysql_down.sh    
            TCP_CHECK {
                connect_timeout 3
                nb_get_retry 3
                delay_before_retry 3
            }
        }
    }

状态参数后可以是bash命令,也可以是shell脚本,内容根据自己需求定义,以上示例中所涉及状态脚本如下:

1) 当服务器改变为主时执行此脚本

1
2
3
4
5
6
# cat to_master.sh 
#!/bin/bash
Date=$(date +%F" "%T)
IP=$(ifconfig eth0 |grep "inet addr" |cut -d":" -f2 |awk '{print $1}')
Mail="baojingtongzhi@163.com"
echo "$Date $IP change to master." |mail -s "Master-Backup Change Status" $Mail

2) 当服务器改变为备时执行此脚本

1
2
3
4
5
6
# cat to_backup.sh
#!/bin/bash
Date=$(date +%F" "%T)
IP=$(ifconfig eth0 |grep "inet addr" |cut -d":" -f2 |awk '{print $1}')
Mail="baojingtongzhi@163.com"
echo "$Date $IP change to backup." |mail -s "Master-Backup Change Status" $Mail

3) 当服务器改变为故障时执行此脚本

1
2
3
4
5
6
# cat to_fault.sh
#!/bin/bash
Date=$(date +%F" "%T)
IP=$(ifconfig eth0 |grep "inet addr" |cut -d":" -f2 |awk '{print $1}')
Mail="baojingtongzhi@163.com"
echo "$Date $IP change to fault." |mail -s "Master-Backup Change Status" $Mail

4) 当检测TCP端口3306为不可用时,执行此脚本,杀死keepalived,实现切换

1
2
3
4
5
6
7
# cat mysql_down.sh
#!/bin/bash
Date=$(date +%F" "%T)
IP=$(ifconfig eth0 |grep "inet addr" |cut -d":" -f2 |awk '{print $1}')
Mail="baojingtongzhi@163.com"
pkill keepalived
echo "$Date $IP The mysql service failure,kill keepalived." |mail -s "Master-Backup MySQL Monitor" $Mail

5) 当检测TCP端口3306可用时,执行此脚本

1
2
3
4
5
6
# cat mysql_up.sh
#!/bin/bash
Date=$(date +%F" "%T)
IP=$(ifconfig eth0 |grep "inet addr" |cut -d":" -f2 |awk '{print $1}')
Mail="baojingtongzhi@163.com"
echo "$Date $IP The mysql service is recovery." |mail -s "Master-Backup MySQL Monitor" $Mail

将linux主机接入到网络中

前言:

这篇博客的主旨就想文章题目说的那样,当我们拿到一台新的系统时,我们怎么实现让你的主机连接到网络中。配置网络就是给你的系统配置IP地址,子网掩码,网关以及DNS。也就是说配置好这几项计算机上网的主要条件,就能实现你的系统联网了。此外,配置网络总结来讲有两种方法;一是通过命令直接配置。通过命令配置的网络知识暂时实现系统联网,想要游泳联网就要通过把配置内容写入配置文件来实现了。配置网络虽然步骤并不复杂但是其背后的知识量还是相当庞大的,我们只有了解其中的配置原理才能正确高效的去配置网络从而实现计算机联网。这篇博客主要介绍了配置网络的常用命令,以及配置文件。通过示例的形式让你更直观的去理解配置方法。CentOS7版本经过改版以后这部分内容与之前的CentOS版本相差较大,我会把CentOS7版本的相关知识分开单独介绍。

配置网络的内容:

IP/mask
路由:默认网关
DNS:服务器指向,域名解析
主DNS服务器
次DNS服务器
第三DNS服务器

配置方式:

  1. 静态指定
    命令:
    ifcfg: ifconfig,route…
    ip: link,addr,route…
    编辑配置文件
    system-config-network-tui
  2. 动态分配
    DHCP: Dynamic Host Configuration Protocol

    配置网络接口

    接口命名方式:
    CentOS 6:不稳定
    以太网:eth [0,1,2,3,…]
    CentOS7:
    网络接口的命名方式有所变化:网络接口的命名与物理环境有关。

ifcfg命令家族

ifconfig,route,netstat

ifconfig:

用来配置网络接口的命令,立即生效,但不是永久生效。
ifconfig [interface] #不加接口显示本机所有活动状态的网络接口,加接口只显示指定接口的信息
ifconfig -a # 显示本机所有网络接口
ifconfig IFACE [up|down] #启用禁用网络接口
ifconfig interface [aftype] options | address …
ifconfig IFACE IP/netmask [up] #修改网络地址
示例:ifconfig eth1 172.18.45.61/16
第二种写法相对复杂所以不用
ifconfig IFACE IP netmask NETMASK
注意:立即生效 启
启用混杂模式:[-]promisc #加-号禁用混杂模式

route:

路由管理命令 ,配置路由信息
route -n #查看路由信息
route add #添加路由
写法:
route add [-net|-host] target [netmask Nm] [gw Gw] [[dev] If]
-net :指定添加网络路由
-host:指定添加主句路由
如果目标网络是0.0.0.0那么表示添加的是一个默认路由
target:目标网络,如果目标是一个主机,那么表示目标主机的IP地址,如果目标是一个网,那么表示网络
gw:网关
dev:指定本地网卡
示例:
增加主机路由:
目标:192.168.1.3 网关:172.18.0.1
route add -host 192.168.1.3 gw 172.18.0.1 dev eth0 #添加主机路由默认mask值是32位精确匹配,所以不用写
增加网络路由:
目标:192.168.0.0 网关:172.18.0.1
route add -net 192.168.0.0/24 gw 172.18.0.1 dev eth0
增加默认路由:
route add default gw 172.18.0.1
删除主机路由:
目标:192.168.1.3 网关172.18.0.1
route dal -host 192.168.1.3
删除网络路由:
目标:192.168.0.0 网关:172.18.0.1
route del -net 192.168.0.0/24

netstat:

网络状态查看命令

显示网络连接:

netstat [–tcp|-t] [–udp|-u] [–raw|-w] [-listening|-l] [–all|-a] [–numeric|-n] [–extend|-e-extend|-e]][–program|-p]
-t: 显示TCP协议的相关链接
-u:显示UDP协议的相关链接
-w:显示裸套接字的相关链接,不经过传输层,由应用层直接调用ARP进行数据传输。
-l:只显示监听状态的连接
-a:显示所有连接
-n:不反解IP地址
-e:拓展格式
-p:显示与哪个程序建立连接
常用组合:
-tan:所有TCP相关的连接
-uan:所有UDP相关的连接
-tnl:TCP协议下,处于监听状态的连接
-unl:UDP协议下处于监听状态的连接(虽然UDP协议下没有网络状态的概念,但是仍然可以这样使用)

显示路由表:

netstat {–route|-r} [–numeric|-n]
-r: 显示内核路由表
-n: 数字格式

显示接口统计数据:

netstat {–interfaces|-I|-i} [iface] [–all|-a] [-extend|-e] [–program|-p] [–numeric|-n]
netstat -i #显示所有网络接口数据
netstat –IIFACE #显示指定接口网络数据I与接口名之间不能有空格
netstat -Ieth0
ifconfig -s eth0

总结:

ifcfg家族命令:ifconfig,route,netstat

ip家族:

配置Linux网络属性:ip命令和ss命令

ip:

ip工具主要作用:显示或配置路由和设备
用法:ip [ OPTIONS ] OBJECT { COMMAND | help }
OBJECT := { link | addr | route }

连接设备管理工具
子命令:

  1. set :设置
  2. show :显示
    set dev IFACE
    可设置属性:
    up and down:激活或禁用指定接口
    ifup/ifdown
    show [dev IFACE]:指定接口
    [up]:仅显示处于激活状态的接口

    ip addr:

    协议地址管理工具
    用法: ip addr { add | del… } IFADDR dev STRING
    子命令:

  3. add:增加指定接口的辅助IP地址
    三个选用项:
    [label PATTERN] :给指定接口添加别名
    [scope {global|link|host}]:指明作用域
    global: 全局可用
    link: 仅链接可用
    host: 本机可用
    [broadcast ADDRESS]:指明广播地址
    示例:ip addr add 172.16.100.100/16 dev eth0 label eth0:0
  4. del:删除指定接口的IP地址
    示例:ip addr del 172.16.100.100/16 dev eth0 label eth0:0
  5. replace:替换指定接口的IP地址
  6. show:显示指定接口的IP地址
  7. flush:清空指定接口或者指定别名的IP地址
    ip address flush dev
  8. change:修改指定接口的IP地址

    ip route

    路由管理工具
    添加路由:ip route add
    ip route add TARGET via GW dev IFACE src SOURCE_IP
    TARGET:
    主机路由:IP
    网络路由:NETWORK/MASK
    示例:
    添加网络路由:ip route add 193.168.0.0/24 via 172.18.0.1
    添加主机路由:ip route add 192.168.1.13 via 172.18.0.1
    添加网关:ip route add default via GW dev IFACE
    ip route add default via 172.18.0.1
    删除路由:
    ip route del TARGET
    删除默认路由:
    ip route del default
    显示和清空路由表:
    ip route show
    ip route flush

    ss:

    网络状态查看命令,与nestat命令用法相似,用来代替nestat命令
    使用格式:ss [OPTION]… [FILTER]
    选项:
    -t: tcp协议相关
    -u: udp协议相关
    -w: 裸套接字相关
    -x:unix sock相关
    -l: listen状态的连接
    -a: 所有
    -n: 数字格式
    -p: 相关的程序及PID
    -e: 扩展的信息
    -m:内存用量
    -o:计时器信息
    条件过滤FILTER : [ state TCP-STATE ] [ EXPRESSION ]
    TCP的常见状态:
    tcp finite state machine:
    LISTEN: 监听
    ESTABLISHED:已建立的连接
    FIN_WAIT_1
    FIN_WAIT_2
    SYN_SENT
    SYN_RECV
    CLOSED
    EXPRESSION:
    dport =
    sport =
    示例:’( dport = :ssh or sport = :ssh )’
    常用组合: -tan, -tanl, -tanlp, -uan
    常见用法:
    ss -l 显示本地打开的所有端口
    ss -pl 显示每个进程具体打开的socket
    ss -t -a 显示所有tcp socket
    ss -u -a 显示所有的UDP Socekt
    ss -o state established ‘( dport = :ssh or sport = :ssh )’ 显示所有已建立的ssh连接
    ss -o state established ‘( dport = :http or sport = :http )’ 显示所有已建立的HTTP连接
    ss -s 列出当前socket详细信息

网络配置文件

/etc/sysconfig/network-scripts/ifcfg-IFACE

IP、MASK、GW、DNS相关配置文件
配置属性:

  1. DEVICE:此配置文件应用到的设备
  2. HWADDR:对应的设备的MAC地址
  3. BOOTPROTO:激活此设备时使用的地址配置协议
    常 用的地址配置协议:
    dhcp:自动获取IP
    static:静态指定IP
    none:不用协议,与static效果相同
    bootp
  4. NM_CONTROLLED:NM是NetworkManager的简写, 此网卡是否接受NM控制;建议CentOS6为“no”
  5. ONBOOT:在系统引导时是否激活此设备
  6. TYPE:接口类型;常见有的Ethernet, Bridge
  7. UUID:设备的惟一标识
  8. IPADDR:如果使用的地址配置协议是手动指定的话需要指明IP地址,如果设定开机自动获取IP那么不用指定
  9. NETMASK:子网掩码
  10. GATEWAY: 默认网关
  11. DNS1:第一个DNS服务器指向
  12. DNS2:第二个DNS服务器指向
  13. USERCTL:普通用户是否可控制此设备
  14. PEERDNS:如果BOOTPROTO的值为“dhcp”,是否允许 dhcp server分配的dns服务器指向信息直接覆盖至 /etc/resolv.conf文件中

/etc/sysconfig/network-scripts/route-IFACE

路由配置文件,需要手动创建
注意:需service network restart生效
两种配置风格:

(1) TARGET via GW
如:10.0.0.0/8 via 172.16.0.1

(2) 每三行定义一条路由
ADDRESS#=TARGET
NETMASK#=mask
GATEWAY#=GW
注意:两种风格不混合使用

设置网卡别名:

将多个IP地址绑定到一个NIC上 eth0:1 、eth0:2、 eth0:3
ifconfig命令:
ifconfig eth0:0 192.168.1.100/24 up
ifconfig eth0:0 down
ip命令: ip addr add 172.16.1.2/16 dev eth0
ip addr add 172.16.1.1/16 dev eth0 label eth0:0
ip addr add 172.16.1.2/16 dev eth0 label eth0:0
ip addr del 172.16.1.1/16 dev eth0 label eth0:0
ip addr flush dev eth0 label eth0:0
编辑配置文件:
为每个设备别名生成独立的接口配置文件
• 关闭NetworkManager服务
ifcfg-ethX:xxx
• 必须使用静态联网
DEVICE=eth0:0
IPADDR=10.10.10.10
NETMASK=255.0.0.0
ONPARENT=yes
注意:service network restart 生效
参考/usr/share/doc/initscripts-*/sysconfig.txt

setup

/etc/sysconfig/network

配置当前主机的主机名
hostname [HOSTNAME]
HOSTNAME=
NETWORKING=yes #网络总开关
不会立即生效,重启机器后生效与hostname [HOSTNAME] 命令配合使用

/etc/hosts

本地主机名数据库和IP地址的映像
• 对小型独立网络有用
• 通常,在使用DNS前检查
• getent hosts 查看/etc/hosts 内容

/etc/udev/rules.d/70-persistent-net.rules

网络接口并命名相关的udev配置文件
编辑修改后并不会立即生效
生效方法:
卸载网卡驱动:modprobe -r e1000
装载 网卡驱动:modprobe e1000

CentOS7 网络配置

网卡命名:

CentOS 6之前,网络接口使用连续号码命名:eth0、eth1等,当 增加或删除网卡时,名称可能会发生变化
CentOS 7使用基于硬件,设备拓扑和设置类型命名:

(1) 网卡命名机制 systemd对网络设备的命名方式

(a) 如果Firmware或BIOS为主板上集成的设备提供的索引信 息可用,且可预测则根据此索引进行命名,例如eno1

(b) 如果Firmware或BIOS为PCI-E扩展槽所提供的索引信息 可用,且可预测,则根据此索引进行命名,例如ens1

(c) 如果硬件接口的物理位置信息可用,则根据此信息进行命 名,例如enp2s0

(d) 如果用户显式启动,也可根据MAC地址进行命名, enx2387a1dc56

(e) 上述均不可用时,则使用传统命名机制
基于BIOS支持启用biosdevname软件
内置网卡:em1,em2
pci卡:pYpX Y:slot ,X:port

(2) 名称组成格式
en: Ethernet 有线局域网
wl: wlan 无线局域网
ww: wwan无线广域网
名称类型:
o

网卡设备的命名过程:

第一步:
udev, 辅助工具程序/lib/udev/rename_device /usr/lib/udev/rules.d/60-net.rules
第二步: biosdevname 会根据/usr/lib/udev/rules.d/71biosdevname.rules
第三步: 通过检测网络接口设备,根据
/usr/lib/udev/rules.d/75-net-description ID_NET_NAME_ONBOARD
ID_NET_NAME_SLOT
ID_NET_NAME_PATH

设置传统网卡命名方式

  1. 编辑/etc/default/grub配置文件
    GRUB_CMDLINE_LINUX=”rhgb quiet net.ifnames=0″
    或:修改/boot/grub2/grub.cfg
  2. 为grub2生成配置文件
    grub2-mkconfig -o /etc/grub2.cfg
  3. 重启系统
    建议直接修改配置文件,将/boot/grub2/grub.cfg文件中内核区域以linux16开头的行,看到fhgb quiet字样后边加net.ifnames=0 之后修改/etc/sysconfig/network-scripts文件中的DEVICE项目和NAME项目。另外文件名手动修改,定义别名生效。

    nmcli:

    CentOS7地址配置工具
    与IP命令相似
    用法:
    nmcli [ OPTIONS ] OBJECT { COMMAND | help }
    nmcli 命令强大的命令补全功能:

    [root@CentOS7 ~]#nmcli 
    agent       device      help        networking  
    connection  general     monitor     radio      
    [root@CentOS7 ~]#nmcli connection 
    add    delete  edit   help    load     monitor  show  
    clone  down    export import   modify   reload   up  
    [root@CentOS7 ~]#nmcli device 
    connect   disconnect  lldp     monitor  set   status
    delete    help     modify      reapply  show   wifi

    常用的两个OBJECT:

    1. connection:

    相当于addr用于配置IP地址
    子命令: start, stop, and manage network connections
    修改IP地址示例:
    nmcli connection modify IFACE [+|-] setting.property value
    [+|-] #表示添加或者删除ip地址
    setting.property:
    ipv4.addresses
    ipv4.gateway
    ipv4.dns1
    ipv4.method #ipv4的地址获取方式
    manual | auto #手动或者自动(手动配置的ip地址立即生效)
    创建新连接static,指定静态IP,不自动连接
    nmcti con add con-name static ifname eth0 autoconnect no type Ethernet ip4 172.25.X.10/24 gw4 172.25.X.254

2. device :

相当于link管理连接设备
子命令:show and manage network interfaces
设备即网络接口,连接是对网络接口的配置。一个网络接口 可有多个连接配置,但同时只有一个连接配置生效

修改配置文件执行生效:

systemctl restart network
nmcli con reload
这篇博客是否对你配置网络有帮助呢?有问题以及指教的地方请留言交流吧。

Nginx URL重写(rewrite)

Nginx URL重写(rewrite)介绍

和apache等web服务软件一样,rewrite的组要功能是实现RUL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持

rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。

rewrite语法格式及参数语法说明如下:

    rewrite    <regex>    <replacement>    [flag];

关键字      正则        替代内容          flag标记

 

关键字:其中关键字error_log不能改变

正则:perl兼容正则表达式语句进行规则匹配

替代内容:将正则匹配的内容替换成replacement

flag标记:rewrite支持的flag标记

 

flag标记说明:

last  #本条规则匹配完成后,继续向下匹配新的location URI规则

break  #本条规则匹配完成即终止,不再匹配后面的任何规则

redirect  #返回302临时重定向,浏览器地址会显示跳转后的URL地址

permanent  #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

rewrite参数的标签段位置:

server,location,if

例子:

rewrite ^/(.*) http://www.czlun.com/$1 permanent;

说明:

rewrite为固定关键字,表示开始进行rewrite匹配规则

regex部分是 ^/(.*) ,这是一个正则表达式,匹配完整的域名和后面的路径地址

replacement部分是http://www.czlun.com/$1 $1,是取自regex部分()里的内容。匹配成功后跳转到的URL。

flag部分 permanent表示永久301重定向标记,即跳转到新的 http://www.czlun.com/$1 地址上

regex 常用正则表达式说明

字符 描述
\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ 匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“oll”,但不能匹配“o”
? 匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
. 匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式。
(pattern) 匹配括号内pattern并可以在后面获取对应的匹配,常用$0…$9属性获取小括号中的匹配内容,要匹配圆括号字符需要\(Content\)

rewrite 企业应用场景

Nginx的rewrite功能在企业里应用非常广泛:

u 可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。

u 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。

u 网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com

u 根据特殊变量、目录、客户端的信息进行URL调整等

Nginx配置rewrite过程介绍

(1)创建rewrite语句

vi conf/vhost/www.abc.com.conf

#vi编辑虚拟主机配置文件

文件内容

server {

listen 80;

server_name abc.com;

rewrite ^/(.*) http://www.abc.com/$1 permanent;

}

 

 

server {

listen 80;

server_name www.abc.com;

location / {

root /data/www/www;

index index.html index.htm;

}

error_log    logs/error_www.abc.com.log error;

access_log    logs/access_www.abc.com.log    main;

}

或者

server {

listen 80;

server_name abc.com www.abc.com;

if ( $host != ‘www.abc.com’  ) {

rewrite ^/(.*) http://www.abc.com/$1 permanent;

}

location / {

root /data/www/www;

index index.html index.htm;

}

error_log    logs/error_www.abc.com.log error;

access_log    logs/access_www.abc.com.log    main;

}

(2)重启服务

确认无误便可重启,操作如下:

nginx -t

#结果显示ok和success没问题便可重启

nginx -s reload

(3)查看跳转效果

打开浏览器访问abc.com

页面打开后,URL地址栏的abc.com变成了www.abc.com说明URL重写成功。

mysqlbinlog日志数据恢复

众所周知,binlog日志对于mysql数据库来说是十分重要的。在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定时全备份+binlog日志恢复增量数据部分),化险为夷!

废话不多说,下面是梳理的binlog日志操作解说:

一、初步了解binlog
MySQL的二进制日志binlog可以说是MySQL最重要的日志,它记录了所有的DDL和DML语句(除了数据查询语句select),以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。
———————————————————————————————————————————————-
DDL
—-Data Definition Language 数据库定义语言
主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用。

DML
—-Data Manipulation Language 数据操纵语言
主要的命令是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言
———————————————————————————————————————————————-

mysqlbinlog常见的选项有以下几个:
–start-datetime:从二进制日志中读取指定等于时间戳或者晚于本地计算机的时间
–stop-datetime:从二进制日志中读取指定小于时间戳或者等于本地计算机的时间 取值和上述一样
–start-position:从二进制日志中读取指定position 事件位置作为开始。
–stop-position:从二进制日志中读取指定position 事件位置作为事件截至

*********************************************************************

一般来说开启binlog日志大概会有1%的性能损耗。
binlog日志有两个最重要的使用场景:
1)MySQL主从复制:MySQL Replication在Master端开启binlog,Master把它的二进制日志传递给slaves来达到
master-slave数据一致的目的。
2)自然就是数据恢复了,通过使用mysqlbinlog工具来使恢复数据。
binlog日志包括两类文件:
1)二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件
2)二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句select)语句事件。

二、开启binlog日志:
1)编辑打开mysql配置文件/etc/mys.cnf
[root@vm-002 ~]# vim /etc/my.cnf
在[mysqld] 区块添加
log-bin=mysql-bin 确认是打开状态(mysql-bin 是日志的基本名或前缀名);

2)重启mysqld服务使配置生效
[root@vm-002 ~]# /etc/init.d/mysqld stop
[root@vm-002 ~]# /etc/init.d/mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]

3)查看binlog日志是否开启
mysql> show variables like ‘log_%’;
+———————————+———————+
| Variable_name | Value |
+———————————+———————+
| log_bin | ON |
| log_bin_trust_function_creators | OFF |
| log_bin_trust_routine_creators | OFF |
| log_error | /var/log/mysqld.log |
| log_output | FILE |
| log_queries_not_using_indexes | OFF |
| log_slave_updates | OFF |
| log_slow_queries | OFF |
| log_warnings | 1 |
+———————————+———————+
9 rows in set (0.00 sec)

三、常用的binlog日志操作命令
1)查看所有binlog日志列表
mysql> show master logs;
+——————+———–+
| Log_name | File_size |
+——————+———–+
| mysql-bin.000001 | 149 |
| mysql-bin.000002 | 4102 |
+——————+———–+
2 rows in set (0.00 sec)

2)查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000002 | 4102 | | |
+——————+———-+————–+——————+
1 row in set (0.00 sec)

3)flush刷新log日志,自此刻开始产生一个新编号的binlog日志文件
mysql> flush logs;
Query OK, 0 rows affected (0.13 sec)

mysql> show master logs;
+——————+———–+
| Log_name | File_size |
+——————+———–+
| mysql-bin.000001 | 149 |
| mysql-bin.000002 | 4145 |
| mysql-bin.000003 | 106 |
+——————+———–+
3 rows in set (0.00 sec)

注意:
每当mysqld服务重启时,会自动执行此命令,刷新binlog日志;在mysqldump备份数据时加 -F 选项也会刷新binlog日志;

4)重置(清空)所有binlog日志
mysql> reset master;
Query OK, 0 rows affected (0.12 sec)

mysql> show master logs;
+——————+———–+
| Log_name | File_size |
+——————+———–+
| mysql-bin.000001 | 106 |
+——————+———–+
1 row in set (0.00 sec)

四、查看binlog日志内容,常用有两种方式:
1)使用mysqlbinlog自带查看命令法:
注意:
–>binlog是二进制文件,普通文件查看器cat、more、vim等都无法打开,必须使用自带的mysqlbinlog命令查看
–>binlog日志与数据库文件在同目录中
–>在MySQL5.5以下版本使用mysqlbinlog命令时如果报错,就加上 “–no-defaults”选项

查看mysql的数据存放目录,从下面结果可知是/var/lib//mysql
[root@vm-002 ~]# ps -ef|grep mysql
root 9791 1 0 21:18 pts/0 00:00:00 /bin/sh /usr/bin/mysqld_safe –datadir=/var/lib/mysql –socket=/var/lib/mysql/mysql.sock –pid-file=/var/run/mysqld/mysqld.pid –basedir=/usr –user=mysql
mysql 9896 9791 0 21:18 pts/0 00:00:00 /usr/libexec/mysqld –basedir=/usr –datadir=/var/lib/mysql –user=mysql –log-error=/var/log/mysqld.log –pid-file=/var/run/mysqld/mysqld.pid –socket=/var/lib/mysql/mysql.sock
root 9916 9699 0 21:18 pts/0 00:00:00 mysql -px xxxx
root 9919 9715 0 21:23 pts/1 00:00:00 grep –color mysql

[root@vm-002 ~]# cd /var/lib/mysql/
[root@vm-002 mysql]# ls
ibdata1 ib_logfile0 ib_logfile1 mysql mysql-bin.000001 mysql-bin.000002 mysql-bin.index mysql.sock ops test

使用mysqlbinlog命令查看binlog日志内容,下面截取其中的一个片段分析:
[root@vm-002 mysql]# mysqlbinlog mysql-bin.000002
…………..
# at 624
#160925 21:29:53 server id 1 end_log_pos 796 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1474810193/*!*/;
insert into member(`name`,`sex`,`age`,`classid`) values(‘wangshibo’,’m’,27,’cls1′),(‘guohuihui’,’w’,27,’cls2′)        #执行的sql语句
/*!*/;
# at 796
#160925 21:29:53 server id 1 end_log_pos 823 Xid = 17                  #执行的时间
………….

解释:
server id 1 : 数据库主机的服务号;
end_log_pos 796: sql结束时的pos节点
thread_id=11: 线程号

2)上面这种办法读取出binlog日志的全文内容比较多,不容易分辨查看到pos点信息
下面介绍一种更为方便的查询命令:
命令格式:
mysql> show binlog events [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count];
参数解释:
IN ‘log_name’ :指定要查询的binlog文件名(不指定就是第一个binlog文件)
FROM pos :指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
LIMIT [offset,] :偏移量(不指定就是0)
row_count :查询总条数(不指定就是所有行)

mysql> show master logs;
+——————+———–+
| Log_name | File_size |
+——————+———–+
| mysql-bin.000001 | 125 |
| mysql-bin.000002 | 823 |
+——————+———–+
2 rows in set (0.00 sec)

mysql> show binlog events in ‘mysql-bin.000002’\G;
*************************** 1. row ***************************
Log_name: mysql-bin.000002
Pos: 4
Event_type: Format_desc
Server_id: 1
End_log_pos: 106
Info: Server ver: 5.1.73-log, Binlog ver: 4
*************************** 2. row ***************************
Log_name: mysql-bin.000002
Pos: 106
Event_type: Query
Server_id: 1
End_log_pos: 188
Info: use `ops`; drop table customers
*************************** 3. row ***************************
Log_name: mysql-bin.000002
Pos: 188
Event_type: Query
Server_id: 1
End_log_pos: 529
Info: use `ops`; CREATE TABLE IF NOT EXISTS `member` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(16) NOT NULL,
`sex` enum(‘m’,’w’) NOT NULL DEFAULT ‘m’,
`age` tinyint(3) unsigned NOT NULL,
`classid` char(6) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
*************************** 4. row ***************************
Log_name: mysql-bin.000002
Pos: 529
Event_type: Query
Server_id: 1
End_log_pos: 596
Info: BEGIN
*************************** 5. row ***************************
Log_name: mysql-bin.000002
Pos: 596
Event_type: Intvar
Server_id: 1
End_log_pos: 624
Info: INSERT_ID=1
*************************** 6. row ***************************
Log_name: mysql-bin.000002
Pos: 624
Event_type: Query
Server_id: 1
End_log_pos: 796
Info: use `ops`; insert into member(`name`,`sex`,`age`,`classid`) values(‘wangshibo’,’m’,27,’cls1′),(‘guohuihui’,’w’,27,’cls2′)
*************************** 7. row ***************************
Log_name: mysql-bin.000002
Pos: 796
Event_type: Xid
Server_id: 1
End_log_pos: 823
Info: COMMIT /* xid=17 */
7 rows in set (0.00 sec)

ERROR:
No query specified

mysql>

上面这条语句可以将指定的binlog日志文件,分成有效事件行的方式返回,并可使用limit指定pos点的起始偏移,查询条数!
如下操作示例:
a)查询第一个(最早)的binlog日志:
mysql> show binlog events\G;

b)指定查询 mysql-bin.000002这个文件:
mysql> show binlog events in ‘mysql-bin.000002’\G;

c)指定查询 mysql-bin.000002这个文件,从pos点:624开始查起:
mysql> show binlog events in ‘mysql-bin.000002’ from 624\G;

d)指定查询 mysql-bin.000002这个文件,从pos点:624开始查起,查询10条(即10条语句)
mysql> show binlog events in ‘mysql-bin.000002’ from 624 limit 10\G;

e)指定查询 mysql-bin.000002这个文件,从pos点:624开始查起,偏移2行(即中间跳过2个),查询10条
mysql> show binlog events in ‘mysql-bin.000002’ from 624 limit 2,10\G;

五、利用binlog日志恢复mysql数据

以下对ops库的member表进行操作
mysql> use ops;
mysql> CREATE TABLE IF NOT EXISTS `member` (
-> `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> `name` varchar(16) NOT NULL,
-> `sex` enum(‘m’,’w’) NOT NULL DEFAULT ‘m’,
-> `age` tinyint(3) unsigned NOT NULL,
-> `classid` char(6) DEFAULT NULL,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.10 sec)

mysql> show tables;
+—————+
| Tables_in_ops |
+—————+
| member |
+—————+
1 row in set (0.00 sec)

mysql> desc member;
+———+———————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———+———————+——+—–+———+—————-+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | | NULL | |
| sex | enum(‘m’,’w’) | NO | | m | |
| age | tinyint(3) unsigned | NO | | NULL | |
| classid | char(6) | YES | | NULL | |
+———+———————+——+—–+———+—————-+
5 rows in set (0.00 sec)

事先插入两条数据
mysql> insert into member(`name`,`sex`,`age`,`classid`) values(‘wangshibo’,’m’,27,’cls1′),(‘guohuihui’,’w’,27,’cls2′);
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
+—-+———–+—–+—–+———+
2 rows in set (0.00 sec)

下面开始进行场景模拟:
1)
ops库会在每天凌晨4点进行一次完全备份的定时计划任务,如下:
[root@vm-002 ~]# crontab -l
0 4 * * * /usr/bin/mysqldump -uroot -p -B -F -R -x –master-data=2 ops|gzip >/opt/backup/ops_$(date +%F).sql.gz

这里手动执行下,将ops数据库备份到/opt/backup/ops_$(date +%F).sql.gz文件中:
[root@vm-002 ~]# mysqldump -uroot -p -B -F -R -x –master-data=2 ops|gzip >/opt/backup/ops_$(date +%F).sql.gz
Enter password:
[root@vm-002 ~]# ls /opt/backup/
ops_2016-09-25.sql.gz
—————–
参数说明:
-B:指定数据库
-F:刷新日志
-R:备份存储过程等
-x:锁表
–master-data:在备份语句里添加CHANGE MASTER语句以及binlog文件及位置点信息
—————–
待到数据库备份完成,就不用担心数据丢失了,因为有完全备份数据在!!

由于上面在全备份的时候使用了-F选项,那么当数据备份操作刚开始的时候系统就会自动刷新log,这样就会自动产生
一个新的binlog日志,这个新的binlog日志就会用来记录备份之后的数据库“增删改”操作
查看一下:
mysql> show master status;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000003 | 106 | | |
+——————+———-+————–+——————+
1 row in set (0.00 sec)

也就是说, mysql-bin.000003 是用来记录4:00之后对数据库的所有“增删改”操作。

2)
早上9点上班了,由于业务的需求会对数据库进行各种“增删改”操作。
比如:在ops库下member表内插入、修改了数据等等:

先是早上进行插入数据:
mysql> insert into ops.member(`name`,`sex`,`age`,`classid`) values(‘yiyi’,’w’,20,’cls1′),(‘xiaoer’,’m’,22,’cls3′),(‘zhangsan’,’w’,21,’cls5′),(‘lisi’,’m’,20,’cls4′),(‘wangwu’,’w’,26,’cls6′);
Query OK, 5 rows affected (0.08 sec)
Records: 5 Duplicates: 0 Warnings: 0

mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | xiaoer | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

3)
中午又执行了修改数据操作:
mysql> update ops.member set name=’李四’ where id=4;
Query OK, 1 row affected (0.07 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> update ops.member set name=’小二’ where id=2;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | 小二 | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | 李四 | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

4)
在下午18:00的时候,悲剧莫名其妙的出现了!
手贱执行了drop语句,直接删除了ops库!吓尿!
mysql> drop database ops;
Query OK, 1 row affected (0.02 sec)

5)
这种时候,一定不要慌张!!!
先仔细查看最后一个binlog日志,并记录下关键的pos点,到底是哪个pos点的操作导致了数据库的破坏(通常在最后几步);

先备份一下最后一个binlog日志文件:
[root@vm-002 ~]# cd /var/lib/mysql/
[root@vm-002 mysql]# cp -v mysql-bin.000003 /opt/backup/
`mysql-bin.000003′ -> `/opt/backup/mysql-bin.000003′
[root@vm-002 mysql]# ls /opt/backup/
mysql-bin.000003 ops_2016-09-25.sql.gz

接着执行一次刷新日志索引操作,重新开始新的binlog日志记录文件。按理说mysql-bin.000003
这个文件不会再有后续写入了,因为便于我们分析原因及查找ops节点,以后所有数据库操作都会写入到下一个日志文件。
mysql> flush logs;
Query OK, 0 rows affected (0.13 sec)

mysql> show master status;
+——————+———-+————–+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000004 | 106 | | |
+——————+———-+————–+——————+
1 row in set (0.00 sec)

6)
读取binlog日志,分析问题。
读取binlog日志的方法上面已经说到。
方法一:使用mysqlbinlog读取binlog日志:
[root@vm-002 ~]# cd /var/lib/mysql/
[root@vm-002 mysql]# mysqlbinlog mysql-bin.000003

方法二:登录服务器,并查看(推荐此种方法)
mysql> show binlog events in ‘mysql-bin.000003′;

+——————+—–+————-+———–+————-+—————————————————————————————————————————-+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+——————+—–+————-+———–+————-+—————————————————————————————————————————-+
| mysql-bin.000003 | 4 | Format_desc | 1 | 106 | Server ver: 5.1.73-log, Binlog ver: 4 |
| mysql-bin.000003 | 106 | Query | 1 | 173 | BEGIN |
| mysql-bin.000003 | 173 | Intvar | 1 | 201 | INSERT_ID=3 |
| mysql-bin.000003 | 201 | Query | 1 | 444 | use `ops`; insert into ops.member(`name`,`sex`,`age`,`gsan’,’w’,21,’cls5′),(‘lisi’,’m’,20,’cls4′),(‘wangwu’,’w’,26,’cls6′) |
| mysql-bin.000003 | 444 | Xid | 1 | 471 | COMMIT /* xid=66 */ |
| mysql-bin.000003 | 471 | Query | 1 | 538 | BEGIN |
| mysql-bin.000003 | 538 | Query | 1 | 646 | use `ops`; update ops.member set name=’李四’ where id= |
| mysql-bin.000003 | 646 | Xid | 1 | 673 | COMMIT /* xid=68 */ |
| mysql-bin.000003 | 673 | Query | 1 | 740 | BEGIN |
| mysql-bin.000003 | 740 | Query | 1 | 848 | use `ops`; update ops.member set name=’小二’ where id= |
| mysql-bin.000003 | 848 | Xid | 1 | 875 | COMMIT /* xid=69 */ |
| mysql-bin.000003 | 875 | Query | 1 | 954 | drop database ops |
| mysql-bin.000003 | 954 | Rotate | 1 | 997 | mysql-bin.000004;pos=4 |
+——————+—–+————-+———–+————-+—————————————————————————————————————————-+
13 rows in set (0.00 sec)

或者:

mysql> show binlog events in ‘mysql-bin.000003’\G;
………
………
*************************** 12. row ***************************
Log_name: mysql-bin.000003
Pos: 875
Event_type: Query
Server_id: 1
End_log_pos: 954
Info: drop database ops
*************************** 13. row ***************************
Log_name: mysql-bin.000003
Pos: 954
Event_type: Rotate
Server_id: 1
End_log_pos: 997
Info: mysql-bin.000004;pos=4
13 rows in set (0.00 sec)

通过分析,造成数据库破坏的pos点区间是介于 875–954 之间(这是按照日志区间的pos节点算的),只要恢复到875前就可。

7)
先把凌晨4点全备份的数据恢复:
[root@vm-002 ~]# cd /opt/backup/
[root@vm-002 backup]# ls
mysql-bin.000003 ops_2016-09-25.sql.gz
[root@vm-002 backup]# gzip -d ops_2016-09-25.sql.gz
[root@vm-002 backup]# mysql -uroot -p -v < ops_2016-09-25.sql
Enter password:
————–
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */
————–

————–
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */
————–

………….
………….

————–
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */
————–

这样就恢复了截至当日凌晨(4:00)前的备份数据都恢复了。

mysql> show databases;                        #发现ops库已经恢复回来了
mysql> use ops;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+—————+
| Tables_in_ops |
+—————+
| member |
+—————+
1 row in set (0.00 sec)

mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
+—-+———–+—–+—–+———+
2 rows in set (0.00 sec)

mysql>

但是这仅仅只是恢复了当天凌晨4点之前的数据,在4:00–18:00之间的数据还没有恢复回来!!
怎么办呢?
莫慌!这可以根据前面提到的mysql-bin.000003的新binlog日志进行恢复。

8)
从binlog日志恢复数据
恢复命令的语法格式:
mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库名

——————————————————–
常用参数选项解释:
–start-position=875 起始pos点
–stop-position=954 结束pos点
–start-datetime=”2016-9-25 22:01:08″ 起始时间点
–stop-datetime=”2019-9-25 22:09:46″ 结束时间点
–database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)
——————————————————–
不常用选项:
-u –user=name 连接到远程主机的用户名
-p –password[=name] 连接到远程主机的密码
-h –host=name 从远程主机上获取binlog日志
–read-from-remote-server 从某个MySQL服务器上读取binlog日志
——————————————————–
小结:实际是将读出的binlog日志内容,通过管道符传递给mysql命令。这些命令、文件尽量写成绝对路径;

a)完全恢复(需要手动vim编辑mysql-bin.000003,将那条drop语句剔除掉)
[root@vm-002 backup]# /usr/bin/mysqlbinlog /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

b)指定pos结束点恢复(部分恢复):
–stop-position=471 pos结束节点(按照事务区间算,是471)
注意:
此pos结束节点介于“member表原始数据”与更新“name=’李四’”之前的数据,这样就可以恢复到更改“name=’李四’”之前的数据了。
操作如下:
[root@vm-002 ~]# /usr/bin/mysqlbinlog –stop-position=471 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | xiaoer | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

恢复截止到更改“name=’李四’”之间的数据(按照事务区间算,是673)
[root@vm-002 ~]# /usr/bin/mysqlbinlog –stop-position=673 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | 李四 | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

c)指定pso点区间恢复(部分恢复):
更新 name=’李四’ 这条数据,日志区间是Pos[538] –> End_log_pos[646],按事务区间是:Pos[471] –> End_log_pos[673]

更新 name=’小二’ 这条数据,日志区间是Pos[740] –> End_log_pos[848],按事务区间是:Pos[673] –> End_log_pos[875]

c1)
单独恢复 name=’李四’ 这步操作,可这样:
按照binlog日志区间单独恢复:
[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-position=538 –stop-position=646 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

按照事务区间单独恢复
[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-position=471 –stop-position=673 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

c2)
单独恢复 name=’小二’ 这步操作,可这样:
按照binlog日志区间单独恢复:
[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-position=740 –stop-position=848 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

按照事务区间单独恢复
[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-position=673 –stop-position=875 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

c3)
将 name=’李四’、name=’小二’ 多步操作一起恢复,需要按事务区间,可这样:
[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-position=471 –stop-position=875 –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

查看数据库:
mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | 小二 | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | 李四 | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

这样,就恢复了删除前的数据状态了!!

—————–
另外:
也可指定时间节点区间恢复(部分恢复):
除了用pos节点的办法进行恢复,也可以通过指定时间节点区间进行恢复,按时间恢复需要用mysqlbinlog命令读取binlog日志内容,找时间节点。

如上,误删除ops库后:
先进行全备份恢复
[root@vm-002 backup]# mysql -uroot -p -v < ops_2016-09-25.sql

查看ops数据库
mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
+—-+———–+—–+—–+———+
2 rows in set (0.00 sec)

mysql>

查看mysq-bin00003日志,找出时间节点
[root@vm-002 ~]# cd /var/lib/mysql
[root@vm-002 mysql]# mysqlbinlog mysql-bin.000003
………….
………….
BEGIN
/*!*/;
# at 173
#160925 21:57:19 server id 1 end_log_pos 201 Intvar
SET INSERT_ID=3/*!*/;
# at 201
#160925 21:57:19 server id 1 end_log_pos 444 Query thread_id=3 exec_time=0 error_code=0
use `ops`/*!*/;
SET TIMESTAMP=1474811839/*!*/;
insert into ops.member(`name`,`sex`,`age`,`classid`) values(‘yiyi’,’w’,20,’cls1′),(‘xiaoer’,’m’,22,’cls3′),(‘zhangsan’,’w’,21,’cls5′),(‘lisi’,’m’,20,’cls4′),(‘wangwu’,’w’,26,’cls6′)                               #执行的sql语句
/*!*/;
# at 444
#160925 21:57:19 server id 1 end_log_pos 471 Xid = 66    #开始执行的时间
COMMIT/*!*/;
# at 471
#160925 21:58:41 server id 1 end_log_pos 538 Query thread_id=3 exec_time=0 error_code=0    #结束时间
SET TIMESTAMP=1474811921/*!*/;
BEGIN
/*!*/;
# at 538
#160925 21:58:41 server id 1 end_log_pos 646 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1474811921/*!*/;
update ops.member set name=’李四’ where id=4     #执行的sql语句
/*!*/;
# at 646
#160925 21:58:41 server id 1 end_log_pos 673 Xid = 68    #开始执行的时间
COMMIT/*!*/;
# at 673
#160925 21:58:56 server id 1 end_log_pos 740 Query thread_id=3 exec_time=0 error_code=0   #结束时间
SET TIMESTAMP=1474811936/*!*/;
BEGIN
/*!*/;
# at 740
#160925 21:58:56 server id 1 end_log_pos 848 Query thread_id=3 exec_time=0 error_code=0
SET TIMESTAMP=1474811936/*!*/;
update ops.member set name=’小二’ where id=2      #执行的sql语句
/*!*/;
# at 848
#160925 21:58:56 server id 1 end_log_pos 875 Xid = 69   #开始执行的时间
COMMIT/*!*/;
# at 875
#160925 22:01:08 server id 1 end_log_pos 954 Query thread_id=3 exec_time=0 error_code=0    #结束时间
SET TIMESTAMP=1474812068/*!*/;
drop database ops
/*!*/;
# at 954
#160925 22:09:46 server id 1 end_log_pos 997 Rotate to mysql-bin.000004 pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

恢复到更改“name=’李四’”之前的数据
[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-datetime=”2016-09-25 21:57:19″ –stop-datetime=”2016-09-25 21:58:41″ –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | xiaoer | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-datetime=”2016-09-25 21:58:41″ –stop-datetime=”2016-09-25 21:58:56″ –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops
mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | guohuihui | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | 李四 | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

[root@vm-002 ~]# /usr/bin/mysqlbinlog –start-datetime=”2016-09-25 21:58:56″ –stop-datetime=”2016-09-25 22:01:08″ –database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops
mysql> select * from member;
+—-+———–+—–+—–+———+
| id | name | sex | age | classid |
+—-+———–+—–+—–+———+
| 1 | wangshibo | m | 27 | cls1 |
| 2 | 小二 | w | 27 | cls2 |
| 3 | yiyi | w | 20 | cls1 |
| 4 | 李四 | m | 22 | cls3 |
| 5 | zhangsan | w | 21 | cls5 |
| 6 | lisi | m | 20 | cls4 |
| 7 | wangwu | w | 26 | cls6 |
+—-+———–+—–+—–+———+
7 rows in set (0.00 sec)

这样,就恢复了删除前的状态了!

总结:
所谓恢复,就是让mysql将保存在binlog日志中指定段落区间的sql语句逐个重新执行一次而已。

***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************

mysql主从复制故障一则

给数据库用户配置
groupadd mysql
useradd -g mysql mysql -s /sbin/nologin
rm -rf /home/mysql
mkdir -p /opt/mysql
chmod -R 755 /opt/mysql

chown -R mysql:mysql /opt/mysql

准备工作:安装基本依赖包,先用yum安装cmake、automake 、autoconf ,另MySQL 5.5.x需要最少安装的包有:bison,gcc、gcc-c++、ncurses-devel

yum -y install gcc gcc-c++ autoconf bison automake zlib* fiex* libxml* ncurses-devel libmcrypt* libtool-ltdl-devel*

安装cmake(mysql5.5以后是通过cmake来编译的)

axel -n  10 http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz
tar zxvf cmake-2.8.4.tar.gz
./bootstrap
gmake install
下载解压mysql 5.5.11
axel  -n 10 http://mirrors.sohu.com/mysql/MySQL-5.5/mysql-5.5.30.tar.gz
tar zxfv  mysql-5.5.30.tar.gz

cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \

-DMYSQL_DATADIR=/opt/mysql \

-DSYSCONFDIR=/etc \

-DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \

-DMYSQL_USER=mysql \

-DMYSQL_TCP_PORT=3306 \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_ARCHIVE_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=0 \

-DWITH_PARTITION_STORAGE_ENGINE=1 \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_SSL=no \

-DEXTRA_CHARSETS=all \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DWITH_READLINE=1 \

-DWITH_ZLIB=system \

-DINSTALL_PLUGINDIR=lib64/mysql/plugin \

-DINSTALL_LIBDIR=lib64/mysql \

-DINSTALL_INCLUDEDIR=include/mysql \

-DWITH_DEBUG=0

碰到了错误:
— Could NOT find Curses (missing:  CURSES_LIBRARY CURSES_INCLUDE_PATH)
CMake Error at cmake/readline.cmake:83 (MESSAGE):
 Curses library not found.  Please install appropriate package,
     remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu, package name is libncurses5-dev, on Redhat and derivates it is ncurses-devel.
Call Stack (most recent call first):
 cmake/readline.cmake:127 (FIND_CURSES)
 cmake/readline.cmake:217 (MYSQL_USE_BUNDLED_LIBEDIT)
 CMakeLists.txt:269 (MYSQL_CHECK_READLINE)
— Configuring incomplete, errors occurred!
是因为少了ncurses-devel这个包。
用yum安装后,然后把目录下的CMakeCache.txt 删除,否则还是报之前的错误
然后就是make  && make  install
cp support-files/my-medium.cnf /etc/my.cnf
chown -R mysql:mysql mysql/
opt]# /opt/mysql/scripts/mysql_install_db –user=mysql  –defaults-file=/etc/my.cnf –basedir=/usr/local/mysql –datadir=/opt/data
/usr/local/mysql/bin/mysqld_safe –user=mysql &  启动mysql
cp  mysql-5.5.30/support-files/mysql.server /etc/init.d/mysqld
chmod +x  /etc/init.d/mysqld
chown .mysql  /etc/init.d/mysqld

chkconfig –add  mysqld

chkconfig mysqld  on

接下来开始部署主从环境

在主服务器上配置mysql的配置文件

确保/etc/my.cnf中有如下参数,没有的话需手工添加,并重启mysql服务。
[mysqld]
log-bin=mysql-bin 启动二进制文件
server-id=1 服务器ID

然后进入到mysql数据库里进行授权

grant replication slave on *.* to ‘backup’@’x.x.x.x’ identified by ‘backup’;

查询主数据库状态,并记下FILE及Position的值,这个在后面配置从服务器的时候要用到

show master status;

+——————+———-+————–+——————+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+——————+———-+————–+——————+

| mysql-bin.000010 |      264 |              |                  |

+——————+———-+————–+——————+

1 row in set (0.00 sec)

主数据库的操作就到这里,下面的操作在从服务器上操作

确保/etc/my.cnf中有log-bin=mysql-bin和server-id=1参数,并把server-id=1修改为server-id=10。修改之后如下所示:
[mysqld]
log-bin=mysql-bin 启动二进制文件
server-id=10 服务器ID
重启mysql服务。登录mysql,执行如下语句
change master to master_host=’o.o.o.o’,master_user=’backup’,master_password=’backup’,master_log_file=’mysql-bin.000010′,master_log_pos=264;
启动slave同步。
start slave;
检查主从同步,如果您看到Slave_IO_Running和Slave_SQL_Running均为Yes,则主从复制连接正常。
show slave status\G

注: 删除mysql日志文件后报I/O error reading the header from the binary log, errno=175, io cache

data目录下日志文件很多,很烦,把mysql-bin.000001~mysql-bin.0000018都删掉了。结果报以下错误:

120914 10:23:31 [ERROR] I/O error reading the header from the binary log, errno=175, io cache code=0

120914 10:23:31 [ERROR] I/O error reading the header from the binary log

120914 10:23:31 [ERROR] Can’t init tc log

120914 10:23:31 [ERROR] Aborting

解决办法:

把剩下的有关日志的文件都删掉。把ibdata1,ib_logfile0,ib_logfile1,mysql-bin.index,再启动就可以了

mysql权限管理

MySQL分为普通用户与root用户。这两种用户的权限不一样。

一、权限表

安装MySQL时会自动安装一个名为mysql的数据库。mysql数据库里面存储的都是权限表。

1、User表

user表有39个字段。这些字段可以分为4类:

  • 用户列;
  • 权限列;
  • 安全列;
  • 资源控制列;

1、用户列

用户列包括Host、User、Password,分别表示主机名、用户名和密码。登录用的就是这个用户名与密码;

2、权限列

user表的权限列包括Select_priv、Insert_priv等以priv结尾的字段。

这些字段的值只有Y和N。Y表示该权限可以用到所有数据库上;N表示该权限不能用到所有数据库上;

通常,可以使用GRANT语句Wie用户赋予一些权限,也可以通过Update语句更新user表的方式来设置权限;

不过,修改user表之后,一定要执行一下FLUSH PRIVILEGES,否则可能会出现如下错误:

Error (1133): Can’t find any matching row in the user table

说明
Select_priv 确定用户是否可以通过SELECT命令选择数据
Insert_priv 确定用户是否可以通过INSERT命令插入数据
Update_priv 确定用户是否可以通过UPDATE命令修改现有数据
Delete_priv 确定用户是否可以通过DELETE命令删除现有数据
Create_priv 确定用户是否可以创建新的数据库和表
Drop_priv 确定用户是否可以删除现有数据库和表
Reload_priv 确定用户是否可以执行刷新和重新加载MySQL所用各种内部缓存的特定命令,包括日志、权限、主机、查询和表
Shutdown_priv 确定用户是否可以关闭MySQL服务器。在将此权限提供给root账户之外的任何用户时,都应当非常谨慎
Process_priv 确定用户是否可以通过SHOW PROCESSLIST命令查看其他用户的进程
File_priv 确定用户是否可以执行SELECT INTO OUTFILE和LOAD DATA INFILE命令
Grant_priv 确定用户是否可以将已经授予给该用户自己的权限再授予其他用户
References_priv 目前只是某些未来功能的占位符;现在没有作用
Index_priv 确定用户是否可以创建和删除表索引
Alter_priv 确定用户是否可以重命名和修改表结构
Show_db_priv 确定用户是否可以查看服务器上所有数据库的名字,包括用户拥有足够访问权限的数据库
Super_priv 确定用户是否可以执行某些强大的管理功能,例如通过KILL命令删除用户进程,使用SET GLOBAL修改全局MySQL变量,执行关于复制和日志的各种命令
Create_tmp_table_priv 确定用户是否可以创建临时表
Lock_tables_priv 确定用户是否可以使用LOCK TABLES命令阻止对表的访问/修改
Execute_priv 确定用户是否可以执行存储过程
Repl_slave_priv 确定用户是否可以读取用于维护复制数据库环境的二进制日志文件。此用户位于主系统中,有利于主机和客户机之间的通信
Repl_client_priv 确定用户是否可以确定复制从服务器和主服务器的位置
Create_view_priv 确定用户是否可以创建视图
Show_view_priv 确定用户是否可以查看视图或了解视图如何执行
Create_routine_priv 确定用户是否可以更改或放弃存储过程和函数
Alter_routine_priv 确定用户是否可以修改或删除存储函数及函数
Create_user_priv 确定用户是否可以执行CREATE USER命令,这个命令用于创建新的MySQL账户
Event_priv 确定用户能否创建、修改和删除事件
Trigger_priv 确定用户能否创建和删除触发器

Update修改权限:

UPDATE user SET Select_priv = 'N'
WHERE Host = '%'

GRANT赋予权限

3、安全列

user表的安全列有4个字段:

  • ssl_type;
  • ssl_cipher;
  • x509_issuer;
  • x509_subject;

ssl用于加密;x509标准可以用来标识用户。普通的发行版都没有加密功能。可以使用SHOW VARIABLES LIKE ‘have_openssl’语句来查看是否具有ssl功能。如果取值为DISABLED,那么则没有ssl加密功能。

4、资源控制列

user表的4个资源控制列是:

  • max_questions:每小时可以允许执行多少次查询;
  • max_updates:每小时可以允许执行多少次更新;
  • max_connections:每小时可以建立多少连接;
  • max_user_connections:单个用户可以同时具有的连接数。

默认值为0,表示无限制。

2、db表和host表

db表存储了某个用户对一个数据库的权限。

host表中存储了某个主机对数据库的操作权限,配合db表对给定主机上数据库级操作权限做更细致的控制;但是很少用,新版本已经取消了host表;

1、用户列

db表的用户列有3个字段:

  • Host:主机名;
  • Db:数据库名;
  • User:用户名;

2、权限列

db表:

  • Create_routine_priv:是否具有创建存储过程权限;
  • Alter_routine_priv:是否具有修改存储过程权限;

user表中的权限是针对所有数据库的,如果user表中的Select_priv字段取值为Y,那么该用户可以查询所有数据库中的表;

如果为某个用户值设置了查询test表的权限,那么user表的Select_priv字段的取值为N。而这个SELECT权限则记录在db表中。db表中的Select_priv字段的取值将会是Y。

用户先根据user表的内容获取权限,然后再根据db表的内容获取权限。

3、tables_priv表和columns_priv表

   tables_priv:可以对单个表进行权限设置:

  • tables_priv表包含8个字段:
  • Host:主机名;
  • DB:数据库名;
  • User:用户名;
  • Table_name:表名
  • Table_priv:对表进行操作的权限(Select,Insert,Update,Delete,Create,Drop,Grant,References,Index,Alter)
  • Column_priv:对表中的数据列进行操作的权限(Select,Insert,Update,Rederences);
  • Timestamp:修改权限的事件
  • Grantor:权限的设置者

columns_priv:可以对单个数据列进行权限设置,有7个列,作用同上:

Host、Db、User、Table_name、Column_name、Column_priv、Timestamp。

  MySQL权限分配是按照user表-> db表 -> table_priv表 -> columns_priv表的顺序进行分配的。

  在数据库系统中,先判断user表中的值是否为’Y’,如果user表中的值是’Y’,就不需要检查后面的表。如果user表为N,则一次检查后面的表。

4、procs_priv表

  • procs_priv表可以对存储过程和存储函数进行权限设置。
  • procs_priv表包含8个字段,分别是:
  • Host:主机名;
  • Db:数据库名;
  • User:用户名;
  • Routine_name:存储过程或函数名称;
  • Routine_type:类型(取值有:FUNCTION或PROCEDURE);
  • Proc_priv:拥有的权限(Execute:执行;Alter Routine:修改;Grant:权限赋予);
  • Timestamp:字段存储更新的时间;
  • Grantor:字段设置者;

二、账户管理

账户管理是MySQL用户管理最基本的内容。包括登录,退出MySQL服务器、创建用户、删除用户、密码管理和权限管理等内容。

其中登录方式非常简单,在这个地址有:http://www.cnblogs.com/kissdodog/p/4154068.html

1、新建普通用户

在MySQL数据库中,建立用户有3种方式:

  • 使用CREATE USER语句来创建新的用户;
  • 直接在mysql.user表中INSERT用户;
  • 使用GRANT语句来新建用户;

1、CREATE USER

使用CREATE USER语句创建用户,必须要拥有CREATE USER权限。其格式如下:

CREATE USER user[IDENTIFIED BY [PASSWORD] 'password'],
[user[IDENTIFIED BY [PASSWORD] 'password']]...

其中,user参数表示新建用户的账户,user由用户名(User)和主机名(Host)构成;IDENTIFIED BY关键字用来设置用户的密码;password参数表示用户的密码;如果密码是一个普通的字符串,就不需要使用PASSWORD关键字。可以没有初始密码。

示例:

CREATE USER 'admin'@'%' IDENTIFIED BY 'admin'

执行之后user表会增加一行记录,但权限暂时全部为‘N’。

2、用INSERT语句新建普通用户

可以使用INSERT语句直接将用户的信息添加到mysql.user表。但必须拥有mysql.user表的INSERT权限。

另外,ssl_cipher、x509_issuer、x509_subject没有值,必须要设置值,否则INSERT语句无法执行。

示例:

INSERT INTO mysql.user(Host,User,Password,ssl_cipher,x509_issuer,x509_subject) VALUES('%','newuser1',PASSWORD('123456'),'','','')

执行INSERT之后,要使用命令:

FLUSH PRIVILEGES

命令来使用户生效。

3、用GRANT语句来新建普通用户

用GRANT来创建新的用户时,能够在创建用户时为用户授权。但需要拥有GRANT权限。

语法如下:

GRANT priv_type ON database.table
TO user[IDENTIFIED BY [PASSWORD] 'password']
[,user [IDENTIFIED BY [PASSWORD] 'password']...]
  • priv_type:参数表示新yoghurt的权限;
  • databse.table:参数表示新用户的权限范围;
  • user:参数新用户的账户,由用户名和主机构成;
  • IDENTIFIED BY关键字用来设置密码;
  • password:新用户密码;

GRANT语句可以同时创建多个用户。

GRANT SELECT ON *.* TO netUser@'%'

*.*与db.*的区别在于。*.*对所有数据库生效,所以user表的SELECT会变为Y。而db.*user表为’N’,更改的是Db表。

2、删除普通用户

1、DROP USER语句删除普通用户

需要拥有DROP USER权限。语法如下:

DROP USER user[,user]...

user是需要删除的用户,由用户名(User)和主机名(Host)构成。

DROP USER 'newuser1'@'%'

2、DELETE语句删除普通用户

可以使用DELETE语句直接将用户的信息从mysql.user表中删除。但必须拥有对mysql.user表的DELETE权限。

DELETE FROM mysql.user WHERE Host = '%' AND User = 'admin'

删除完成后,一样要FLUSH PRIVILEGES才生效。

3、修改密码

1、使用mysqladmin命令来修改root用户的密码

语法:

mysqladmin -u -username -p password "new_password"

新密码(new_password)必须用括号括起来,单引号会报错。

示例:

(注:这个待验证,我怎么执行都不成功!)

2、修改user表

UPDATE user表的passwor字段的值,也可以达到修改密码的目的;

UPDATE user SET Password = PASSWORD('123') WHERE USER = 'myuser'

FLUSH PRIVILEGES后生效。

3、使用SET语句来修改密码

使用root用户登录到MySQL服务器后,可以使用SET语句来修改密码:

修改自己的密码,不需要用户名

SET PASSWORD = PASSWORD("123");

修改其他用户密码:

SET PASSWORD FOR 'myuser'@'%'=PASSWORD("123456")

FOR 用户名@主机名

4、GRANT语句来修改普通用户的密码

使用GRANT语句修改普通用户的密码,必须拥有GRANT权限。

GRANT priv_type ON database.table TO user [IDENTIFIED BY [PASSWORD] 'password']

示例:

GRANT SELECT ON *.* TO 'test3'@'%' IDENTIFIED BY '123'

4、忘记密码的解决方案

如果root用户密码丢失了,会给用户造成很大的麻烦。但是,可以通过某种特殊方法登录到root用户下,然后修改密码。

1、使用–skip-grant-tables选项启动MySQL服务

该选项将使MySQL服务器停止权限判断,任何用户都能够访问数据库。

在Windows操作系统下,使用mysqlid或mysqlid-nt来启动MySQL服务。

mysqld命令:

mysqld –skip-grant-tables

mysqld-nt命令:

mysqld-nt –skip-grant-tables

net start mysql命令:

net start mysql –skip-grant-tables

2、登录root用户,并且设置新密码

mysql -u root

必须使用UPDATE语句更新mysql数据库下的user表,而不能使用SET语句,因为–skip-grant-tables不能使用SET语句。

修改完密码以后,FLUSH PRIVILEGES语句加载权限表,新密码即生效。

三、权限管理

1、MySQL的各种权限

权限名称 对应user表中的列 权限的范围
CREATE Create_priv 数据库、表或索引
DROP Drop_priv 数据库或表
GRANT OPTION Grant_priv 数据库、表、存储过程或函数
REFERENCES References_priv 数据库或表
ALTER Alter_priv 修改表
DELETE Delete_priv 删除表
INDEX Index_priv 用索引查询表
INSERT Insert_priv 插入表
SELECT Select_priv 查询表
UPDATE Update_priv 更新表
CREATE VIEW Create_view_priv 创建视图
SHOW VIEW Show_view_priv 查看视图
ALTER ROUTINE Alter_routine 修改存储过程或存储函数
CREATE ROUTINE Create_routine_priv 创建存储过程或存储函数
EXECUTE Execute_priv 执行存储过程或存储函数
FILE File_priv 加载服务器主机上的文件
CREATE TEMPORARY TABLES Create_temp_table_priv 创建临时表
LOCK TABLES Lock_tables_priv 锁定表
CREATE USER Create_user_priv 创建用户
PROCESS Process_priv 服务器管理
RELOAD Reload_priv 重新加载权限表
REPLICATION CLIENT Repl_client_priv 服务器管理
REPLICATION SLAVE Repl_slave_priv 服务器管理
SHOW DATABASES Show_db_priv 查看数据库
SHUTDOWN Shutdown_priv 关闭服务器
SUPER Super_priv 超级权限

 

2、授权

GRANT语法如下:

GRANT priv_type [(column_list)] ON database.table
TO user [IDENTIFIED BY [PASSWORD] 'password']
[,user [IDENTIFIED BY [PASSWORD] 'password']]...
WITH with_option[with_option]
  • priv_type参数表示权限类型;
  • column_list:参数表示权限作用于哪些列上,没设置则位于整个表上;
  • user参数由用户名和主机名构成;形式是”‘username’@’hostname'”;
  • IDENTIFIED BY参数用于为用户设置密码;
  • password:用户新密码;

WITH关键字后面带有一个或多个with_option参数。有5个选项:

  • GRANT OPTION:被授权的用户可以将这些权限赋予给别的用户;
  • MAX_QUERIES_PER_HOUR count:设置没消失可以允许执行count次查询;
  • MAX_UPDATES_PER_HOUR count:设置每个消失可以允许执行count次更新;
  • MAX_CONNECTIONS_PER_HOUR count:设置每小时可以建立count个连接;
  • MAX_USER_CONNECTIONS count:设置单个用户可以同时具有的count个连接数;

示例:

GRANT SELECT,UPDATE ON *.*
    TO 'myuser'@'%'
WITH GRANT OPTION;

3、收回权限

收回权限,就是取消某个用户的某些权限。MySQL中使用REVOKE关键字来为用户设置权限。

语法如下:

REVOKE priv_type[(column_list)]
ON database.table
FROM user[,user]

收回全部权限的REVOKE语句的基本语法如下:

REVOKE ALL PRIVILEGES,GRANT OPTION FROM user[,user]...

示例:回收用户myuser的SELECT权限

REVOKE SELECT ON *.*FROM 'myuser'@'%'

收回myuser的所有权限:

REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'myuser'@'%'

4、查看权限

SHOW GRANTS语句用于查看权限。同时mysql数据库下的user表中存储着用户的基本权限。

SELECT * FROM mysql.user

SHOW GRANTS

 

tomcat优化

当一个进程有 500 个线程在跑的话,那性能已经是很低很低了。Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。

当某个应用拥有 250 个以上并发的时候,应考虑应用服务器的集群。
具体能承载多少并发,需要看硬件的配置,CPU 越多性能越高,分配给 JVM 的内存越多性能也就越高,但也会加重 GC 的负担。
操作系统对于进程中的线程数有一定的限制:
Windows 每个进程中的线程数不允许超过 2000
Linux 每个进程中的线程数不允许超过 1000
另外,在 Java 中每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用。
Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有很大关系的。更好的硬件,更多的处理器都会使Tomcat支持更多的并发。
Tomcat 默认的 HTTP 实现是采用阻塞式的 Socket 通信,每个请求都需要创建一个线程处理。这种模式下的并发量受到线程数的限制,但对于 Tomcat 来说几乎没有 BUG 存在了。
Tomcat 还可以配置 NIO 方式的 Socket 通信,在性能上高于阻塞式的,每个请求也不需要创建一个线程进行处理,并发能力比前者高。但没有阻塞式的成熟。
这个并发能力还与应用的逻辑密切相关,如果逻辑很复杂需要大量的计算,那并发能力势必会下降。如果每个请求都含有很多的数据库操作,那么对于数据库的性能也是非常高的。
对于单台数据库服务器来说,允许客户端的连接数量是有限制的。
并发能力问题涉及整个系统架构和业务逻辑。
系统环境不同,Tomcat版本不同、JDK版本不同、以及修改的设定参数不同。并发量的差异还是满大的。

maxThreads=”1000″ 最大并发数
minSpareThreads=”100″///初始化时创建的线程数
maxSpareThreads=”500″///一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。
acceptCount=”700″// 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理

配置实例:
<Connector port=”8080″ protocol=”HTTP/1.1″ minSpareThreads=”100″ maxSpareThreads=”500″ maxThreads=”1000″ acceptCount=”700″
connectionTimeout=”20000″
redirectPort=”8443″ />

 

 

以下是一个配置实例:

 

<Executor name=”tomcatThreadPool” # 配置TOMCAT共享线程池,NAME为名称
namePrefix=”HTTP-8088-exec-” # 线程的名字前缀,用于标记线程名称
prestartminSpareThreads=”true” # executor启动时,是否开启最小的线程数
maxThreads=”5000″ # 允许的最大线程池里的线程数量,默认是200,大的并发应该设置的高一些,这里设置可以支持到5000并发
maxQueueSize=”100″ # 任务队列上限
minSpareThreads=”50″ # 最小的保持活跃的线程数量,默认是25.这个要根据负载情况自行调整了。太小了就影响反应速度,太大了白白占用资源
maxIdleTime=”10000″ # 超过最小活跃线程数量的线程,如果空闲时间超过这个设置后,会被关别。默认是1分钟。
/>
[html] view plain copy
<Connector port=”8088″ protocol=”org.apache.coyote.http11.Http11NioProtocol”
connectionTimeout=”5000″ redirectPort=”443″ proxyPort=”443″ executor=”tomcatThreadPool” # 采用上面的共享线程池
URIEncoding=”UTF-8″/>

部署内网Docker Registry

目前docker 已经分为社区版 (docker CE)和 商业版(docker EE),最新的版本由原来的1.13直接跳到了17.06,目前由于17.06的刚刚发布,在使用Docker 的时候可以根据自己的需求选择相应的版本。

Docker 安装

先移除其他非官方的版本:

yum -y remove docker docker-common container-selinux
yum -y remove docker-selinux

添加yum源,这里选择1.13的版本:

yum install -y yum-utils
yum-config-manager --add-repo https://docs.docker.com/v1.13/engine/installation/linux/repo_files/centos/docker.repo

对yum仓库快速缓存:

 yum makecache fast

安装docker:

yum -y install docker-engine-1.13.1

如果对版本有特殊要求,这里可以使用如下命令,列出可选的版本信息,然后指定版本安装:

yum list docker-engine.x86_64  --showduplicates |sort -r

在启动的配置文件中添加国内的镜像仓库:

 vim /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd --registry-mirror https://qxx96o44.mirror.aliyuncs.com
...

启动docker:

systemctl start docker

Docker Registry

我们可以使用docker registry 作为我们的私有镜像仓库,当本地制作好镜像后,可以直接上传到镜像仓库中,方便其他主机拉取镜像。

在生产环境中,官方建议使用权威的CA证书,如果我们可以申请到公共的CA证书,就可以部署我们的共有镜像仓库。

也可以通过创建私有的证书,在需要访问仓库的主机上添加认证即可。

由于目前都是内部使用,加上服务器权限控制非常严格,所以这里直接使用免CA证书的方式(官方强烈不推荐)

修改registry配置为免CA模式,指定Registry服务器的域名或者IP地址,并指定访问端口(端口可任意,和registry容器端口映射上即可)

创建daemon.json:

 vim /etc/docker/daemon.json
{
  "insecure-registries" : ["192.168.60.18:5000"]
}

重启docker 服务:

systemctl restart docker

配置用户密码

mkdir auth

下载registry镜像,并配置账户密码:

docker run  --entrypoint htpasswd registry -Bbn trying 123123 > auth/htpasswd

这个命令会拉取registry镜像,以htpasswd的方式对密码进行加密,指定用户 trying 和密码123123,并将密码存在指定文件中。

启动容器仓库:

docker run -d -p 5000:5000 --restart=always --name registry_docker -v `pwd`/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry:2

指定容器的映射端口,容器启动时应用自动启动,指定一个数据卷,挂载验证文件htpasswd,并指定验证信息。

使用账号登录仓库,输入账号密码:

docker login 192.168.60.18:5000

推送本地镜像到仓库:

docker tag 256ab8c63c04 192.168.60.18:5000/self-registry:v1
docker push 192.168.60.18:5000/self-registry:v1

其他主机下载镜像:

在另外一台需要获取镜像的主机上配置registry为无CA模式:

 vim /etc/docker/daemon.json
{
  "insecure-registries" : ["192.168.60.18:5000"]
}

启动docker, 登录:

docker login 192.168.60.18:5000
docker pull 192.168.60.18:5000/self-registry:v1

拉取成功:

# docker images
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
192.168.60.18:5000/self-registry   v1                  256ab8c63c04        About an hour ago   401 MB

补充说明:

1、内网的其他主机如果需要从本地仓库拉取镜像,都需要添加daemon.json的文件。

2、在registry的容器中,我们可以看到挂载的宿主机磁盘信息:

 # df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                  80.0G      3.3G     76.7G   4% /
/dev/vda1                80.0G      3.3G     76.7G   4% /auth
/dev/vda1                80.0G      3.3G     76.7G   4% /etc/resolv.conf
/dev/vda1                80.0G      3.3G     76.7G   4% /etc/hostname
/dev/vda1                80.0G      3.3G     76.7G   4% /etc/hosts
/dev/vda1                80.0G      3.3G     76.7G   4% /var/lib/registry

在容器中,镜像的存放位置为/var/lib/registry/docker/registry/v2/repositories/  那么对应的宿主机目录是/var/lib/docker/image/

可以在启动registry时挂载宿主机上指定的目录到容器的/var/lib/registry上。

本文出自 “Trying” 博客,请务必保留此出处http://tryingstuff.blog.51cto.com/4603492/1948328