暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

姜老师MYSQL笔记

郭靖师傅看我的眼色行事 2021-10-19
588

22.找出没有主键的表


    SELECT
    table_schema, table_name
    FROM
    information_schema.TABLES --
    WHERE
    table_name NOT IN (
    SELECT DISTINCT
    TABLE_NAME
    FROM
    information_schema.COLUMNS
    WHERE
    COLUMN_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 sec
        2 lock struct(s), heap size 1136, 1 row lock(s)
        MySQL thread id 3, OS thread handle 139787704108800, query id 44 localhost root cleaning up
        TABLE 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 0
        0: 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 no2的物理记录,由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 下查看锁信息


          SELECT
          r.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_query
          FROM
          information_schema.innodb_lock_waits w
          INNER JOIN
          information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
          INNER JOIN
          information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;




          MySQL 5.7 下查看锁信息

          -- 继续执行终端1/终端3 内的SQL语句,使其中有一个线程发生阻塞


            mysql> use sys
            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> 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 -- 等待的事物ID
            waiting_trx_started: 2016-01-25 21:00:04
            waiting_trx_age: 00:00:04
            waiting_trx_rows_locked: 1
            waiting_trx_rows_modified: 0
            waiting_pid: 6
            waiting_query: select * from t5 where a=2 lock in share mode
            waiting_lock_id: 421206427405024:62:3:2 -- 事物ID:space:page_No:heap_no
            waiting_lock_mode: S -- 等待(请求)的锁的类型
            blocking_trx_id: 23592
            blocking_pid: 7
            blocking_query: NULL
            blocking_lock_id: 23592:62:3:2
            blocking_lock_mode: X -- 阻塞的锁的类型
            blocking_trx_started: 2016-01-25 20:59:48
            blocking_trx_age: 00:00:20
            blocking_trx_rows_locked: 2
            blocking_trx_rows_modified: 0
            sql_kill_blocking_query: KILL QUERY 7 -- 给出了建议
            sql_kill_blocking_connection: KILL 7
            1 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 Segment128减小到96,剩余的32rollback 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 grants
                Show grants for current_user;
                Show grants for current_user();
                Show grants for ‘perf’@’127.0.0.1’;
                Select * from mysql.user where user=’perf’\G
                Select * from mysql.db where user=’perf’\G
                Select 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,则执行时间正好等于2SQL语句不会记录

                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\G
                  3.show index from orders\G
                  4.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.processlist
                      where user='root' and time > 200 into outfile '/tmp/a.txt';
                      mysql> source tmp/a.txt;

                      17.检查表的索引创建的情况,判断该索引是否有创建的必要

                      3. TABLES STATISTICS 表中的table_schematable_name相关联

                      -- 通过Cardinalitytable_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_test
                        table_name: test_index_2
                        index_name: idx_mul_ab -- 这个是上次测试复合索引建立的index
                        max(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_schematable_name 让上述的信息和TABLES表进行关联

                          --


                            SELECT
                            t.TABLE_SCHEMA,t.TABLE_NAME,INDEX_NAME, CARDINALITY, TABLE_ROWS,
                            CARDINALITY/TABLE_ROWS AS SELECTIVITY -- 得到选择性
                            FROM
                            TABLES t, -- 查询的表一,TABLES
                            (
                            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 )
                            ) s -- 查询的表二,就是上面3.2的查询结果
                            WHERE
                            t.table_schema = s.table_schema -- 通过库关联
                            AND t.table_name = s.table_name -- 再通过表变量
                            AND t.table_schema = 'employees' -- 指定某一个库名
                            ORDER BY SELECTIVITY;



                            通过最后一列的SELECTIVITY是否接近1,判断该索引创建是否合理

                            -- 注意:

                            -- Cardinalitytable_rows的值,都是通过随机采样,预估得到的

                            -- analyze前后,Cardinality值相差较多,说明该索引是不应该被创建的(页上的记录数值分布不平均)

                            --

                            -- 推荐 SELECTIVITY 15% 以上是适合的

                            --

                            -- 索引使用情况

                            --


                              mysql> select * from x$schema_index_statistics limit 1\G
                              *************************** 1. row ***************************
                              table_schema: employees
                              table_name: employees
                              index_name: PRIMARY -- 索引名字
                              rows_selected: 300024 -- 读取的记录数
                              select_latency: 370177723990 -- 使用该索引读取时总的延迟时间370毫秒(单位是皮秒)
                              rows_inserted: 0 -- 插入的行数
                              insert_latency: 0
                              rows_updated: 0 -- 更新的行数
                              update_latency: 0
                              rows_deleted: 0
                              delete_latency: 0
                              1 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 -- 最后一个刷到磁盘上的页的最新的LSNNEWEST_MODIFICATION

                              Last checkpoint at 4005645488 -- 最后一个刷到磁盘上的页的第一次被修改时的LSNOLDEST_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大于CheckPointLSN ,则表示不需要恢复了;

                              1. 日志中的LSN = CheckPointLSN ,则表示所有页都已经刷回磁盘

                              2. 日志中的LSN > CheckPointLSN ,则表示还有页没刷到磁盘;如果是宕机,则需要用日志恢复。

                              3. 日志中的LSN < CheckPointLSN ,则报错

                              1. 日志(redo)中的LSN

                              假设当前的LSNC ,此时对某个页做修改,则会产生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文件
                                # 暂时忽略Warning
                                Warning: 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
                                # 暂时忽略Warning
                                Warning: 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.sql
                                Warning: 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.sql
                                69c69
                                < -- 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

                                备份的时候dumpCHANGE 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

                                startstop的范围是[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 的时间很多,超过了Masterbinlog的保存时间,那Master上对应的binlog就会被删除,SlaveI/O Thread就拉不到数据了

                                注意监控主从落后的时间


                                mysql> select * from mysql.slave_master_info\G


                                2.6.5. read_onlysuper_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; 才能真正修改为只读。




                                文章转载自郭靖师傅看我的眼色行事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                评论