22.找出没有主键的表
SELECTtable_schema, table_nameFROMinformation_schema.TABLES --WHEREtable_name NOT IN (SELECT DISTINCTTABLE_NAMEFROMinformation_schema.COLUMNSWHERECOLUMN_KEY = 'PRI')AND table_schema NOT IN ('mysql' , 'information_schema','sys', 'performance_schema');
23.查看主键
select * from information_schema.columns where table_name="test_key_2" and column_key="PRI"\G
29锁
mysql> show engine innodb status\G-- ----------省略其他输出----------TRANSACTION 23076, ACTIVE 96 sec2 lock struct(s), heap size 1136, 1 row lock(s)MySQL thread id 3, OS thread handle 139787704108800, query id 44 localhost root cleaning upTABLE LOCK table `burn_test`.`t5` trx id 23076 lock mode IX -- 在表上加上了意向锁IX(TABLE LOCK)RECORD LOCKS space id 62 page no 3 n bits 72 index GEN_CLUST_INDEX of table `burn_test`.`t5` trx id 23076 lock_mode X locks rec but not gap -- X locks rec but not gap 就是记录锁(RECORD LOCK)Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 6; hex 000000000625; asc %;;1: len 6; hex 000000001390; asc ;;2: len 7; hex 610000002c0d5f; asc a , _;;3: len 4; hex 80000002; asc ;;4: len 4; hex 80000002; asc ;;-- Record lock : 表示是锁住的记录-- heap no 2 PHYSICAL RECORD: n_fields 5 : 表示锁住记录的heap no 为2的物理记录,由5个列组成-- compact format : 表示这条记录存储的格式(Dynamic其实也是compact的格式)-- info bits : 0 -- 表示这条记录没有被删除; 非0 -- 表示被修改或者被删除(32)-- 输出上述信息的前提是 innodb_status_output_locks = 1-- 可在配置文件中设置打开,不会影响运行时的性能-- 只有在show engine innodb status时才会使用set innodb_lock_wait_timeout=60; 锁等待时间,一般设置5-10
MySQL5.6 下查看锁信息
SELECTr.trx_id waiting_trx_id,r.trx_mysql_thread_id waiting_thread,r.trx_query waiting_query,b.trx_id blocking_trx_id,b.trx_mysql_thread_id blocking_thread,b.trx_query blocking_queryFROMinformation_schema.innodb_lock_waits wINNER JOINinformation_schema.innodb_trx b ON b.trx_id = w.blocking_trx_idINNER JOINinformation_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;
MySQL 5.7 下查看锁信息
-- 继续执行终端1/终端3 内的SQL语句,使其中有一个线程发生阻塞
mysql> use sysReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql> select * from innodb_lock_waits\G*************************** 1. row ***************************wait_started: 2016-01-25 21:00:04 -- 开始的时间wait_age: 00:00:04 -- 等待的时间wait_age_secs: 4 -- 等待秒数locked_table: `burn_test`.`t5` -- 锁住的表(意向锁)locked_index: GEN_CLUST_INDEX -- 锁住的是系统生成的聚集索引,锁都是在索引上的locked_type: RECORD -- 锁的类型,记录锁waiting_trx_id: 421206427405024 -- 等待的事物IDwaiting_trx_started: 2016-01-25 21:00:04waiting_trx_age: 00:00:04waiting_trx_rows_locked: 1waiting_trx_rows_modified: 0waiting_pid: 6waiting_query: select * from t5 where a=2 lock in share modewaiting_lock_id: 421206427405024:62:3:2 -- 事物ID:space:page_No:heap_nowaiting_lock_mode: S -- 等待(请求)的锁的类型blocking_trx_id: 23592blocking_pid: 7blocking_query: NULLblocking_lock_id: 23592:62:3:2blocking_lock_mode: X -- 阻塞的锁的类型blocking_trx_started: 2016-01-25 20:59:48blocking_trx_age: 00:00:20blocking_trx_rows_locked: 2blocking_trx_rows_modified: 0sql_kill_blocking_query: KILL QUERY 7 -- 给出了建议sql_kill_blocking_connection: KILL 71 row in set (0.01 sec)
MySQL 5.6 通过导入sys库,也可以支持该视图
锁都是锁在索引上的,无论是主键还是二级索引,通过locked_index 进行查看
当超过innodb_lock_wait_timeout 设置的阈值,等待(请求)的事物就会报锁超时。在某些业务场景下,锁超时是无法避免的。
select @@tx_isolation; -- 查看当前事物的隔离级别
READ-COMMITTED | -- 当前是RC的,也就是Oracle,MSSQL 的默认隔离级别,其实是不复合隔离性的要求的
线上环境一般使用READ-COMMITTED
34.binlog
mysql> show master status;show variables like "%max_binlog_size%"; -- binlog 文件的大小show variables like "binlog_format";查看当前binlog中的内容mysql> show binlog events in 'bin.000056';mysql> flush binary logs; -- or flush logs 刷新日志,并且会产生一个新的日志[root@MyServer 5.7]> mysqlbinlog bin.000057 -vv ##增加 -vv 参数,可以看到注释信息注意:这些注释信息不是SQL语句,他只是记录了页的变化show variables like "binlog_rows_query_log_events";打开该参数,可以在row格式下,看到对应的sql信息mysql> set binlog_rows_query_log_events=1;mysql> show variables like "binlog_cache_size";+-------------------+-------+| Variable_name | Value |+-------------------+-------+| binlog_cache_size | 32768 | -- 默认为32K(内存中),线程级别的变量,别设置的太大mysql> show global status like "binlog%";+----------------------------+-------+| Variable_name | Value |+----------------------------+-------+| Binlog_cache_disk_use | 0 | -- 记录了使用临时文件写二进制日志的次数(做监控需要关注这个)| Binlog_cache_use | 6 | -- 记录了使用缓冲写二进制日志的次数| Binlog_stmt_cache_disk_use | 0 || Binlog_stmt_cache_use | 2 |+----------------------------+-------+4 rows in set (0.00 sec)
写日志本来就挺慢的,现在cache写不下,再写入磁盘,然后再写binlog,就是两次写磁盘,就更慢了。
如果参数Binlog_cache_disk_use 次数很多,就要看一下binlog_cache_size 设置是否太小,或者事物本身是否太大
MySQL使用在OLTP的场景下,应该是很快速的小事物。如果有大的事物,应该把大的事物拆成小事物去执行。
36.UNDO
undo默认存放在 ibdata1中,即系统表空间中。
系统表空间中的内容:(ibdata1)
1. double write
2. 元数据信息(数据字典)
3. undo信息(5.6后可分离),分开放可避免竞争
◦ innodb_undo_directory – 表示undo存放的独立目录(比如: /undologs/)
◦ innodb_undo_logs – 表示Rollback segment的个数(比如: 128)
◦ innodb_undo_tablespaces – 存放到哪几个文件中去(比如:3)
4. insert buffer change buffer
在MySQL 5.7以后,Rollback Segment从128个减小到96个,剩余的32个rollback segment 预留给临时表空间( ibtmp1 )使用。
3.用户权限管理
系统表权限信息:
a)用户名和IP是否允许
b)查看您mysql.user表//查看全局所有库的权限
c)查看mysql.db表//查看指定库的权限
d)查看mysql.table_priv表//查看指定表的权限
e)查看mysql.column_priv表//查看指定列的权限
常用权限
SQL语句:SELECT,INSERT,UPDATE,DELETE,INDEX
存储过程:CREATE ROUTINE,ALTER ROUTINE,EXECUTE,TRIGGER
管理权限:SUPER,RELOAD,SHOW DATABASE,SHUTDOWN
显示当前用户的权限
Show grantsShow grants for current_user;Show grants for current_user();Show grants for ‘perf’@’127.0.0.1’;Select * from mysql.user where user=’perf’\GSelect * from mysql.db where user=’perf’\GSelect user();Show databases;
5.慢查询
相关参数:
• slow_query_log
◦ 是否开启慢查询日志
• slow_query_log_file
◦ 慢查询日志文件名, 在my.cnf 我们已经定义为slow.log,默认是机器名-slow.log
• long_query_time
◦ 制定慢查询阈值, 单位是秒,且当版本>=5.5.X ,支持毫秒。例如0.5 即为500ms
◦ 大于该值,不包括值本身。例如该值为2,则执行时间正好等于2的SQL语句不会记录
• log_queries_not_using_indexes
◦ 将没有使用索引的SQL记录到慢查询日志
◾ 如果一开始因为数据少,查表快,耗时的SQL语句没被记录,当数据量大时,该SQL可能会执行很长时间
◾ 需要测试阶段就要发现问题,减小上线后出现问题的概率
• log_throttle_queries_not_using_indexes
◦ 限制每分钟内,在慢查询日志中,去记录没有使用索引的SQL语句的次数;版本需要>=5.6.X
◾ 因为没有使用索引的SQL可能会短时间重复执行,为了避免日志快速增大,限制每分钟的记录次数
• min_examined_row_limit
◦ 扫描记录少于改值的SQL不记录到慢查询日志
◾ 结合去记录没有使用索引的SQL语句的例子,有可能存在某一个表,数据量维持在百行左右,且没有建立索引。这种表即使不建立索引,查询也很快,扫描记录很小,如果确定有这种表,则可以通过此参数设置,将这个SQL不记录到慢查询日志。
• log_slow_admin_statements
◦ 记录超时的管理操作SQL到慢查询日志,比如ALTER/ANALYZE TABLE
• log_output
◦ 慢查询日志的格式,[FILE | TABLE | NONE],默认是FILE;版本>=5.5
◦ 如果设置为TABLE,则记录的到mysql.slow_log
• log_slow_slave_statements
◦ 在从服务器上开启慢查询日志
• log_timestamps
◦ 写入时区信息。可根据需求记录UTC时间或者服务器本地系统时间
如果在线上操作,不需要mysqldumpslow 去扫整个slow.log , 可以去tail -n 10000 slow.log > last_10000_slow.log (10000这个数字根据实际情况进行调整),然后进行mysqldumpslow last_10000_slow.log
15-16.查看索引
1.desc orders;2.show create table orders\G3.show index from orders\G4.select * from information_schema.STATISTICS where table_name='salaries'\G需要主动执行analyze table 才会去采样。采样不会锁表或者锁记录mysql> select * from key_column_usage limit 3\G -- 显示了哪个索引使用了哪个列
注意:EXPLAIN查看的是执行计划,做SQL解析,不会去真的执行;且到5.7以后子查询也不会去执行。
mysql> explain extended select * from test_index_2 where b >1 and b < 3\G参数FORMAT◦ 使用FORMART=JSON 不仅仅是为了格式化输出效果,还有其他有用的显示信息。mysql> explain format=json select * from test_index_2 where b >1 and b < 3\G◦ 且当5.6版本后,使用MySQL Workbench ,可以使用visual Explain 方式显示详细的图示信息show index from lineitem\G查看索引使用情况use sys (sys库,5.7才有)mysql> select * from schema_index_statistics limit 10\G
杀会话
mysql> select concat('KILL ',id,';') from information_schema.processlistwhere user='root' and time > 200 into outfile '/tmp/a.txt';mysql> source tmp/a.txt;
17.检查表的索引创建的情况,判断该索引是否有创建的必要
3. 将TABLES 和 STATISTICS 表中的table_schema和table_name相关联
-- 通过Cardinality和table_rows 计算,即可得到对应索引名的选择性
--
--
-- 3.1 因为存在复合索引,所以我们要取出复合索引中seq最大的哪个值
-- 这样取出的cardinality值才是最大的
--
mysql> select-> table_schema, table_name, index_name,-> max(seq_in_index) -- 取出最大的seq号后,选出index_name等信息-> from-> STATISTICS-> group by table_schema , table_name , index_name\G-- -----------省略其他输出-----------*************************** 10. row ***************************table_schema: burn_testtable_name: test_index_2index_name: idx_mul_ab -- 这个是上次测试复合索引建立的indexmax(seq_in_index): 2 -- 取出了最大的seq-- -----------省略其他输出-----------
--
-- 3.2 得到了最大的seq,从而可以取出对应的cardinality
--
mysql> select-> table_schema, table_name, index_name, cardinality-> from-> STATISTICS-> where-> (table_schema , table_name, index_name, seq_in_index) in-> (select-> table_schema, table_name,-> index_name, max(seq_in_index)-> from-> STATISTICS-> group by table_schema , table_name , index_name)\G
3.3 最后通过table_schema和table_name 让上述的信息和TABLES表进行关联
--
SELECTt.TABLE_SCHEMA,t.TABLE_NAME,INDEX_NAME, CARDINALITY, TABLE_ROWS,CARDINALITY/TABLE_ROWS AS SELECTIVITY -- 得到选择性FROMTABLES t, -- 查询的表一,TABLES(SELECTtable_schema,table_name,index_name,cardinalityFROM STATISTICSWHERE (table_schema,table_name,index_name,seq_in_index) IN (SELECTtable_schema,table_name,index_name,MAX(seq_in_index)FROMSTATISTICSGROUP BY table_schema , table_name , index_name )) s -- 查询的表二,就是上面3.2的查询结果WHEREt.table_schema = s.table_schema -- 通过库关联AND t.table_name = s.table_name -- 再通过表变量AND t.table_schema = 'employees' -- 指定某一个库名ORDER BY SELECTIVITY;
通过最后一列的SELECTIVITY是否接近1,判断该索引创建是否合理
-- 注意:
-- Cardinality和table_rows的值,都是通过随机采样,预估得到的
-- 当analyze前后,Cardinality值相差较多,说明该索引是不应该被创建的(页上的记录数值分布不平均)
--
-- 推荐 SELECTIVITY 15% 以上是适合的
--
-- 索引使用情况
--
mysql> select * from x$schema_index_statistics limit 1\G*************************** 1. row ***************************table_schema: employeestable_name: employeesindex_name: PRIMARY -- 索引名字rows_selected: 300024 -- 读取的记录数select_latency: 370177723990 -- 使用该索引读取时总的延迟时间370毫秒(单位是皮秒)rows_inserted: 0 -- 插入的行数insert_latency: 0rows_updated: 0 -- 更新的行数update_latency: 0rows_deleted: 0delete_latency: 01 row in set (0.00 sec)-- 结合之前的SELECTIVITY和这里的数值,可以更好的判断索引是否合理-- 重启后数据归0
索引是要排序的,建立索引越多,排序以及维护成本会很大,插入数据的速度会变慢,所以索引建立的多,不是仅仅是浪费空间,还会降低性能,增加磁盘IO
注意:MySQL5.6的版本STATISTICS数据存在问题,截止5.6.28仍然存在,官方定性为Bug
作业一:在MySQL5.6 中使用mysql.innodb_index_stats 得到索引的选择性(SELECTIVITY)
24.Buffer_pool
每次读写数据都是通过Buffer Pool ;
◦ 当Buffer Pool 中没有用户所需要的数据时,才去硬盘中获取;
• 通过innodb_buffer_pool_size 进行设置总容量;
• 该值设置的越大越好;
• innodb_buffer_pool_instances 设置为多少个缓冲池;
◦ 总容量还是innodb_buffer_pool_size
◦ 设置多个instance 可将热点打散,提高并发性能(建议设置成CPU个数值,设置大了也没什么伤害)
• Buffer Pool也是以页(page) 为单位的,且大小和innodb_page_size 一致;
mysql> select * from information_schema.INNODB_BUFFER_POOL_STATS\G
从MySQL 5.7 开始,可以在线修改innodb_buffer_pool_size
set global innodb_buffer_pool_size=2*1024*1024*1024; -- 扩大
MySQL 5.7之前的版本,修改该值,需要重启
25. LSN (Log Sequence Number)
mysql> show engine innodb status\G
-- ----------省略其他输出-------------
---
LOG
---
Log sequence number 4005645497 -- 当前内存中最新的LSN
Log flushed up to 4005645497 -- redo刷到磁盘的LSN(不是在内存中的)
Pages flushed up to 4005645497 -- 最后一个刷到磁盘上的页的最新的LSN(NEWEST_MODIFICATION)
Last checkpoint at 4005645488 -- 最后一个刷到磁盘上的页的第一次被修改时的LSN(OLDEST_MODIFICATION)
LSN(Log Sequence Number) 是一个字节数。
注意:
1. Log sequence number 和Log flushed up 这两个LSN可能会不同,运行过程中后者可能会小于前者,因为redo日志也是先在内存中更新,再刷到磁盘的。
2. Pages flushed up 与Last checkpoint 其实都指向了最后一个刷新到磁盘的页,只是Pages flushed up 代表了页中的NEWEST_MODIFICATION ,而Last checkpoint 代表了页中的OLDEST_MODIFICATION 。
◦ FLUSH LIST 使用OLDEST_MODIFICATION 进行记录并排序,那在刷新脏页时, CheckPoint 的LSN 值就对应的是当前刷新到某个页的OLDEST_MODIFICATION ;
◦ 当某个页只被修改过一次,则Pages flushed up 与Last checkpoint 会相等,反之多次修改,则Pages flushed up 大于Last checkpoint ;
◦ 在恢复时,从CheckPoint 开始恢复,如果当前页的LSN大于CheckPoint的LSN ,则表示不需要恢复了;
1. 日志中的LSN = CheckPoint的LSN ,则表示所有页都已经刷回磁盘
2. 日志中的LSN > CheckPoint的LSN ,则表示还有页没刷到磁盘;如果是宕机,则需要用日志恢复。
3. 日志中的LSN < CheckPoint的LSN ,则报错
1. 日志(redo)中的LSN:
◦ 假设当前的LSN为C ,此时对某个页做修改,则会产生M 个字节的日志(需要写入M个字节的日志),那此时的LSN 则为C+M 。依次类推,LSN是一个单调递增的值(字节数)。
◦ 日志中的LSN代表了日志一共写入了多少个字节。
2. 页中的LSN:
页中也存在LSN,表示该页被修改的时候,多应的日志的LSN是多少;
39. mysqldump重要参数
--all-databases :备份所有的数据库
• --databases DB1 [DB2 DB3] :备份指定的数据库
• --single-transaction : 在一个事物中导出,确保产生一致性的备份,当前只对innodb支持
1.1.3. mysqldump演示
shell> mysqldump --databases burn_test -S tmp/mysql.sock_58 > burn_test.sql # 导出的是SQL文件# 暂时忽略WarningWarning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don’t want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.shell> mysqldump --single-transaction --databases burn_test -S tmp/mysql.sock_58 > burn_test_2.sql# 暂时忽略WarningWarning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don’t want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.mysqldump: Couldn't execute 'SAVEPOINT sp': The MySQL server is running with the --transaction-write-set-extraction!=OFF option so it cannot execute this statement (1290)# 产生Error。需要设置下面的参数mysql> set global transaction_write_set_extraction=0;Query OK, 0 rows affected (0.00 sec)shell> mysqldump --single-transaction --databases burn_test -S tmp/mysql.sock_58 > burn_test_2.sqlWarning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don’t want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.#### 从下面的diff看,结果没有差别,## 如果备份的时候由其他事物在进行插入或者修改操作,其实是可以看得出差别的##shell> diff burn_test.sql burn_test_2.sql69c69< -- Dump completed on 2016-03-05 16:19:21---> -- Dump completed on 2016-03-05 16:35:59
single-transaction
1. 当开始备份的时候,备份的是备份点(备份开始的时刻) 时的数据(即使在备份过程中,表中的数据发生了改变)
2. 实现方式:在开启事物前,先设置为RR 隔离级别(事物隔离级别是会话级别,由mysqldump自己设置),由于RR级别解决了不可重复读和幻读问题,所以在备份的时刻开启一个事物后,读取的数据是能保证一致性的
--master-data :
备份的时候dump出CHANGE MASTER 信息(file 和 pos),可供主从复制的时候使用, 默认值为1 。
◦ 当值设置为2 的时候,也会dump出信息,但是会被注释掉
CHANGE MASTER 信息表示,这个mysqldump出来的文件,是在这个MASTER_LOG_FILE 文件的MASTER_LOG_POS 位置备份出来的,是一个起始位置信息
shell> mysqldump --single-transaction --master-data=1 --databases burn_test -S tmp/mysql.sock_58 > burn_test_4.sql
shell> mysqldump --single-transaction --master-data=2 --databases burn_test -S tmp/mysql.sock_58 > burn_test_5.sql
mysql> show master status; -- 就能看到file 和 pos了
40.主从复制
命令flush binary logs; 可以强制刷新binlog到磁盘,并且产生一个新的日志( 重启MySQL 也会产生新的日志)
参数max_binlog_size 可以设置一个binlog日志的最大的大小是多少(为了保证一个事物在一个binlog 中,可能会超过该阈值)
[root@MyServer 5.7.11]> mysqlbinlog bin.000032 –vv
有多个文件要恢复
正确的做法如下:
shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root –p
## ---------------OR----------------
shell> mysqlbinlog binlog.000001 > tmp/statements.sql
shell> mysqlbinlog binlog.000002 >> tmp/statements.sql
## ---------------OR----------------
shell> mysqlbinlog binlog.00000[1-2] > tmp/statements.sql
shell> mysql -u root -p -e "source tmp/statements.sql"
注意:mysqlbinlog的参数start/stop-position 不能是中间位置,必须是在binlog 文件中at 后面跟着的一个数字(必须是一个边界值)。
参数start/stop-datatime 可以通过时间戳来进行恢复
# 基于position
shell> mysqlbinlog bin.000017 --start-position=1959 --stop-position=2057 -vv > tmp/a.sql
# 基于datetime
shell> mysqlbinlog bin.000017 --start-datetime="2016-03-02 21:03:58" --stop-datetime="2016-03-02 23:14:06" -vv > /tmp/a.sql
shell> mysql -u root -p < a.sql
start和stop的范围是[start, stop)
-- 在mysql中查看events信息(from pos limit N,[M])
mysql> show binlog events in 'bin.000003' from 123 limit 5;
mysql> show slave status\G
Slave_IO_Running 和Slave_SQL_Running 这两个指标都为YES ,表示目前的复制的状态是正常的
如果开启了并行复制(multi-threaded slave), show processlist 中可以看到Coordinator 线程
Relay_Log_File 和Relay_Log_Pos 是中继日志(Relay_Log)信息
由于IO线程拉取数据的速度快于SQL线程回放数据的速度,所以Relay_Log 可在两者之间起到一个缓冲的作用
Relay_Log 的格式和binlog 的格式是一样的,但是两者的内容是不一样的(不是和binlog一一对应的)
Relay_Log 在SQL线程回放完成后,(默认)就会被删除,而binlog 不会(由 expire_logs_days 控制)
Relay_Log 可以通过设置relay_log_purge=0 ,使得Relay_Log 不被删除(MHA中不希望被 Purge),需要通过外部的脚本进行删除
在MySQL5.6+以后,将relay_log_info_repository 设置为TABLE ,relay-info将写入到mysql.slave_relay_log_info 这张表中
mysql> select * from mysql.slave_relay_log_info\G
*************************** 1. row ***************************
Number_of_lines: 7
Relay_log_name: ./relay.000010 -- relay日志的文件名
Relay_log_pos: 314 -- relay日志的位置
Master_log_name: bin.000005 -- 对应回放到的 binlog 文件名(Master节点)
Master_log_pos: 478 -- 对应回放到的位置
Sql_delay: 0
Number_of_workers: 4
Id: 1
Channel_name:
1 row in set (0.00 sec)
设置为TABLE 的原理为:将event的回放和relay-info的更新放在同一个事物里面,变成原子操作,从而保证一致性(要么都写入,要么都不写)。
所以说,真正的MySQL复制的高可靠是从5.6 版本开始的,通过设置
• relay-log-recover = 1
• relay_log_info_repository = TABLE
• master_info_repository = TABLE
这三个参数,可以确保整体复制的高可靠(换言之,之前的版本复制不可靠是正常的)。
注意:如果Slave落后Master 的时间很多,超过了Master上binlog的保存时间,那Master上对应的binlog就会被删除,Slave的I/O Thread就拉不到数据了
注意监控主从落后的时间
mysql> select * from mysql.slave_master_info\G
2.6.5. read_only与super_read_only
如果在Slave机器上对数据库进行修改或者删除,会导致主从的不一致,需要对Slave机器设置为read_only = 1 ,让Slave提供只读操作。
注意: read_only 仅仅对没有SUPER权限的用户有效(即 mysql.user表的Super_priv字段为Y),一般给App 的权限是不需要SUPER权限的。
参数super_read_only 可以将有SUPER权限的用户也设置为只读,且该参数设置为ON 后, read_only 也跟着自动设置为ON ;
mysql> show variables like "read_only";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | OFF | -- 一开始为off
+---------------+-------+
1 row in set (0.00 sec)
mysql> set global super_read_only=1; -- 开启super用户的read_only
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like "read_only";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | ON | -- 自动启用
+---------------+-------+
1 row in set (0.00 sec)
注意:当前最新的MySQL5.7.11 中,在/etc/my.cnf 中将super_read_only=1 配置好后重启,还是可以插入或修改数据.
需要在命令行中执行set global super_read_only=1; 才能真正修改为只读。




