MySQL4

MySQL數據庫4

1 管理索引

  • 建立索引幫助
    help CREATE INDEXcss

  • 建立索引html

    1. 指令
      CREATE INDEX
    2. 語法格式
      CREATE INDEX index_name ON tbl_name(index_col_name,…);
    3. 示例
      示例1:在students表中的取name的前十個字符字段增長索引名爲idx_classid
             
             
             
             
             
      • 1
      MariaDB [hellodb]> CREATE INDEX idx_name ON students(name(10));
      示例2:建立複合索引,在(name,age)兩個字段上創建複合索引
             
             
             
             
             
      • 1
      MariaDB [hellodb]> CREATE INDEX idx_name_age ON students(name,age);
      示例3:建立惟一鍵索引,關鍵字CREATE UNIQUE INDEX,惟一鍵命名時最好加上前綴以區分例如uni_idx
             
             
             
             
             
      • 1
      MariaDB [hellodb]> CREATE UNIQUE INDEX uni_idx_name ON students(name);
  • 刪除索引mysql

    1. 語法格式
      DROP INDEX index_name ON tbl_name;
    2. 示例
      刪除在字段students上的索引
             
             
             
             
             
      • 1
      MariaDB [hellodb]> DROP INDEX idx_classid ON students;
      刪除惟一鍵,DROP INDEX或ALTER均可以
             
             
             
             
             
      • 1
      MariaDB [hellodb]> ALTER TABLE students DROP KEY uni_idx_name;
  • 查看索引web

    1. 語法格式
      SHOW INDEXES FROM [db_name.]tbl_name;
    2. 示例
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      '不在表所在庫,顯示索引,須要指定庫名' MariaDB [(none)]> SHOW INDEXES FROM hellodb.students; '進入表所在數據庫後,能夠省略' MariaDB [(none)]> use hellodb MariaDB [hellodb]> show index from students\G
      查看複合索引,顯示效果,以兩行顯示,鍵名相同,分爲2部分
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      *************************** 4. row *************************** Table: students Non_unique: 1 Key_name: idx_name_age <==具備相同的鍵名 Seq_in_index: 1 <==表示Name在組合鍵的前面 Column_name: Name *************************** 5. row *************************** Table: students Non_unique: 1 Key_name: idx_name_age <==與4都屬於複合鍵,相同的鍵名 Seq_in_index: 2 <==表示age在組合鍵的後面 Column_name: Age
      查看惟一鍵索引
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      MariaDB [hellodb]> show index from students\G *************************** 2. row *************************** Table: students Non_unique: 0 <==主鍵和惟一鍵與其餘索引的區別在於,此項爲0 Key_name: uni_idx_name
  • 優化表空間:
    數據庫中表數據文件,在刪除數據後,所佔空間不會自動釋放,須要進行表空間優化才能夠釋放sql

    1. 語法格式
      OPTIMIZE TABLE tb_name
    2. 示例
             
             
             
             
             
      • 1
      MariaDB [hellodb]> OPTIMIZE TABLE students;
  • 查看索引的使用shell

    1. 語法格式
      SHOW INDEX_STATISTICS
    2. 開啓功能相關變量
      userstat
    3. 示例
      須要修改變量userstat爲啓動狀態
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      '1. 查看變量狀態' MariaDB [hellodb]> SHOW VARIABLES LIKE 'userstat'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | userstat | OFF | +---------------+-------+ '2. 修改狀態' MariaDB [hellodb]> SET GLOBAL userstat=1; '3. 查看索引的使用狀況' MariaDB [hellodb]> SHOW INDEX_STATISTICS; +--------------+------------+------------+-----------+ | Table_schema | Table_name | Index_name | Rows_read | +--------------+------------+------------+-----------+ | hellodb | students | index_age | 24 | +--------------+------------+------------+-----------+
  • EXPLAIN分析索引的有效性數據庫

    1. 關鍵字
      EXPLAIN
    2. 語法格式
      EXPLAIN SELECT clause
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      '查詢優化器如何執行查詢' MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE age=20; +------+-------------+----------+------+-------- -------+-----------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+------+---------------+-----------+---------+-------+------+-------+ | 1 | SIMPLE | students | ref | index_age | index_age | 1 | const | 2 | | +------+-------------+----------+------+---------------+-----------+---------+-------+------+-------+
    3. 輸出信息說明:
      參考https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
      1. id
        當前查詢語句中,每一個SELECT語句的編號,包括子句的編號
        複雜類型的查詢有三種:
        1. 簡單子查詢
        2. 用於FROM中的子查詢
        3. 聯合查詢:UNION,UNION查詢的分析結果會出現一個額外匿名臨時表
                     
                     
                     
                     
                     
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          MariaDB [hellodb]> EXPLAIN SELECT name FROM students UNION SELECT name FROM teachers; +------+--------------+------------+-------+---------------+--------------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+--------------+------------+-------+---------------+--------------+---------+------+------+-------------+ | 1 | PRIMARY | students | index | NULL | idx_name_age | 153 | NULL | 25 | Using index | | 2 | UNION | teachers | ALL | NULL | NULL | NULL | NULL | 4 | | | NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | | +------+--------------+------------+-------+---------------+--------------+---------+------+------+------
    4. select_type
      1. 簡單查詢爲SIMPLE
      2. 複雜查詢select_type顯示內容
        1. SUBQUERY:簡單子查詢
        2. PRIMARY:最外面的SELECT
        3. UNION:UNION語句的第一個以後的SELECT語句
        4. UNION RESULT: 匿名臨時表
        5. DERIVED:用於FROM中的子查詢
          要顯示FROM子查詢的類型,須要設置變量optimizer_switch,其中的相關項’derived_merg
                     
                     
                     
                     
                     
          • 1
          MariaDB [hellodb]> SET optimizer_switch='derived_merge=off';
    5. table:SELECT語句關聯到的表
    6. type:關聯類型或訪問類型,即MySQL決定的如何去查詢表中的行的方式,如下順序,性能從低到高
      1. ALL:全表掃描,也就是沒有利用索引
      2. index:根據索引的次序進行全表掃描;若是在Extra列出現「Using index」表示了使用覆蓋索引,而非全表掃描
      3. range:有範圍限制的根據索引實現範圍掃描;掃描位置始於索引中的某一點,結束於另外一點
      4. ref: 根據索引返回表中匹配某單個值的全部行
      5. eq_ref:僅返回一個行,但與須要額外與某個參考值作比較
      6. const, system: 直接返回單個行
    7. possible_keys:查詢可能會用到的索引
    8. key:查詢中使用到的索引
    9. key_len:在索引使用的字節數
    10. ref:在利用key字段所表示的索引完成查詢時所用的列或某常量值
    11. rows:MySQL估計爲找全部的目標行而須要讀取的行數
    12. Extra:額外信息
      1. Using index:MySQL將會使用覆蓋索引,以免訪問表
      2. Using where:MySQL服務器將在存儲引擎檢索後,再進行一次過濾
      3. Using temporary:MySQL對結果排序時會使用臨時表
      4. Using filesort:對結果使用一個外部索引排序
  1. 示例
    1. 索引沒有利用,在表數據不是不少時範圍查詢,查詢結果佔表數據的很大一部分,優化器認爲直接搜索的速度比索引快:
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      '查看錶students中以x開頭的姓名,由下例可知,沒有利用索引,由於此表一共只有25條記錄,而x開頭的行佔了6條' MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'x%'; +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | students | ALL | index_name | NULL | NULL | NULL | 25 | Using where | +------+-------------+----------+------+---------------+------+---------+------+------+-------------+
    2. 冗餘索引示例,前文中已經創建了idx_name和複合鍵idx_name_age索引,試着搜索名字以o開頭的學員,獲得可用索引以下所示,複合鍵的索引機制爲左前綴,而複合鍵idx_name_age的name鍵在左邊,屬於重複現象:
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      MariaDB [hellodb]> EXPLAIN SELECT * FROM students WHERE name LIKE 'o%'; +------+-------------+----------+-------+-------------------------+------------+---------+------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+----------+-------+-------------------------+------------+---------+------+------+-----------------------+ | 1 | SIMPLE | students | range | index_name,idx_name_age | index_name | 152 | NULL | 1 | Using index condition | +------+-------------+----------+-------+-------------------------+------------+---------+------+------+-----------------------+
  • 另外一個查詢優化SQL語句
    若是查詢命令是一個多表查詢,想要知道具體哪一個字查詢拖慢了速度,explain顯示的內容不夠具體,須要另外一個觀察命令的執行過程變量profiling,默認是關閉的
         
         
         
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. '啓用變量' MariaDB [hellodb]> SET profiling=on; 2. '執行一個查詢指令' MariaDB [hellodb]> SELECT a.stuid, a.name FROM (SELECT * FROM students) AS a; 3. '執行profiles觀察查詢過程' MariaDB [hellodb]> SHOW profiles; +----------+------------+--------------------------------------------------------------+ | Query_ID | Duration | Query | +----------+------------+-------------------------------------------------------------- | | 1 | 0.00120368 | SELECT a.stuid, a.name FROM (SELECT * FROM students) AS a | +----------+------------+--------------------------------------------------------------+ 4. '針對編號繼續查詢,就會列出詳細執行過程所用時間' MariaDB [hellodb]> SHOW profile FOR query 1;

2. 併發控制

保證多個用戶同時訪問,互相不干擾vim

2.1 一些概念

  • 鎖分類centos

    1. 鎖粒度
      1. 表級鎖(MyISAM)
      2. 行級鎖(InnoDB)
    2. 以獨佔性來分
      1. 讀鎖:共享鎖,只讀不可寫,多個讀互不阻塞,
      2. 寫鎖:獨佔鎖,排它鎖,一個寫鎖會阻塞其它讀和它鎖
    3. 按是否自動加鎖分類:
      1. 隱式鎖:由存儲引擎自動施加鎖
      2. 顯式鎖:用戶手動請求
  • 實現緩存

    1. 存儲引擎:自行實現其鎖策略和鎖粒度
    2. 服務器級:實現行鎖,表級鎖;用戶可顯式請求
  • 鎖策略
    在鎖粒度及數據安全性尋求的平衡機制,加鎖的缺點爲影響併發性,可是能夠保證數據完整性,在二者之間尋求平衡

2.2 顯式鎖使用

  • 加鎖
    1. SQL語句關鍵字
      LOCK TABLES
    2. 語法格式
             
             
             
             
             
      • 1
      LOCK TABLES tbl_name[[AS] alias] lock_type [, tbl_name[[AS] alias] lock_type] ...
    3. 說明
      1. tbl_name:將加鎖的表名
      2. lock_type: READ |WRITE
        WRITE鎖時,須要注意緩存是否開啓,若是有緩存須要重啓服務或者關閉緩存開關或者將緩存相關的服務器變量quer_cache_wlock_invalidate=on寫入配置文件,不容許其餘用戶從緩存讀取
    4. 示例
      爲表teachers加讀鎖
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      MariaDB [hellodb]> LOCK TABLES teachers READ; 此時不能訪問本數據庫的其餘表格,會報錯,其餘終端不影響 '試着訪問同數據庫的另外一種表students' MariaDB [hellodb]> SELECT * FROM students; ERROR 1100 (HY000): Table 'students' was not locked with LOCK TABLES <==報錯信息
  • 加全局鎖
    1. 語法格式
      FLUSH TABLES [tb_name[,…]] [WITH READ LOCK]
    2. 說明
      將表加鎖,關閉正在打開的表(清除查詢緩存),不指定表,將進行全局加鎖(全部數據庫),一般在備份前加全局讀鎖,FLUSH TABLES爲溫備份,加鎖時會等待全部表格關閉
    3. 示例:使用FLUSH TABLES加鎖時,有未關閉表等待狀態示例
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      '在其餘終端訪問hellodb數據庫表teachers,設置函數sleep(100)休眠100秒,保持訪問狀態' MariaDB [hellodb]> SELECT *,sleep(100) FROM teachers; '利用FLUSH TABLES 爲teachers加只讀鎖' MariaDB [hellodb]> FLUSH TABLES teachers WITH READ LOCK; <==會卡在這裏等待全部表關閉
  • 查詢時加鎖
    1. 加寫鎖
      SELECT clause FOR UPDATE
    2. 加讀鎖
      SELECT clause LOCK IN SHARE MODE
  • 解鎖
    UNLOCK TABLES

2.3 死鎖

  • 什麼是死鎖
    兩個或多個事務在相互佔用彼此資源,並請求鎖定對方佔用的資源的狀態
    在這裏插入圖片描述
  • 解決方法
    回滾其中一個,被回滾的是代價小的,一般爲執行時間短的哪一個事務,系統主動解決
  • 當多事務同時執行時,遇到行鎖鎖定,另外一個用戶處於等待狀態的主動解決方案
    1. 查看事務列表
      SHOW PROMCESSLIST
    2. 結束等待事務
      kill id
    3. 示例
             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      1. '查看事務列表,找出處於等待的' MariaDB [hellodb]> SHOW PROMCESSLIST\G *************************** 7. row *************************** Id: 23 <==kill命令後面的編號 User: root Host: localhost db: hellodb Command: Query Time: 21 State: updating Info: update teachers set age=70 where tid=3 <==處於等待的事務 Progress: 0.000 2. '主動將結束等待狀態' MariaDB [hellodb]> kill 23 <==id爲等待事務編號

3. 事務

事務Transactions:一組原子性的SQL語句,或一個獨立工做單元,有專門的事務日誌記錄操做過程,實現undo,redo等故障恢復功能,來保證數據的一致性

  • ACID特性:

    1. A(atomicity原子性)
      整個事務中的全部操做要麼所有成功執行,要麼所有失敗後回滾
      數據庫執行事務時,先讀入數據到內存,在內存中修改後,放到日誌文件中,所有事務執行完畢後會有一個標記,若是執行過程當中掉電,恢復供電後,日誌文件會根據標記判斷事務是否所有執行完畢,所有執行完畢則寫入磁盤(redo),沒有執行完則捨棄以記錄操做(undo),保證磁盤數據完整性
    2. C(consistency一致性)
      數據庫老是從一個一致性狀態轉換爲另外一個一致性狀態
    3. I(Isolation隔離性)
      一個事務所作出的操做在提交以前,是不能爲其它事務所見;隔離有多種隔離級別,實現併發
    4. D(durability持久性)
      一旦事務提交,其所作的修改會永久保存於數據庫中
  • Transaction生命週期
    在這裏插入圖片描述

    1. LNITIAL DB STATE :數據庫初始一致性狀態
    2. START TRANSACTION:開始事務,對數據庫增刪改
    3. COMMIT:肯定無誤,提交結果,結束事務
    4. NEW DB STATE:新的一致性狀態
    5. ROLLBACK:只要事務沒有提交,就能夠回滾到數據庫初始狀態
  • 使用事務
    在數據庫中執行增刪改就是一個事務,回車執行就結束了此事務,這種系統後臺自動開始,自動提交的事務叫作隱式提交事務,mysql和sql server默認使用自動提交,oracle默認使用的是手動提交須要輸入(commit提交,rollback回滾)

    1. 自動提交是否啓動相關變量
      set autocommit={1|0} 默認爲1,設爲0時爲非自動提交

             
             
             
             
             
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      '1. 在會話A中,將事務提交設置爲非自動提交' MariaDB [(none)]> set autocommit=off; '2. 確認變量狀態' MariaDB [(none)]> show variables like 'autocommit'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | autocommit | OFF | <==已經關掉,會話級的,不影響其餘窗口 +--------------------------+-------+ 3. '修改數據' MariaDB [hellodb]> UPDATE students SET classid=10 SHERE stuid=15; MariaDB [hellodb]> SELECT * FROM students; <==在執行修改命令的終端查看修改 效果 | 15 | Duan Yu | 19 | M | 10 | NULL | <=能夠看到已修改 4. '在B會話中查看' MariaDB [hellodb]> SELECT * FROM students; | 15 | Duan Yu | 19 | M | 4 | NULL | <=因爲事務沒有提交,屬於髒數 據,其餘會話不會顯示 5. '回到A會話,不想修改執行rollback,回滾到最初狀態' MariaDB [hellodb]> ROLLBACK; Query OK, 0 rows affected (0.00 sec) 6. '查看回滾後的結果,數據不變' MariaDB [hellodb]> select * from students; | 15 | Duan Yu | 19 | M | 4 | NULL | 7. '確認事務無誤,提交事務關鍵字爲`commit`,確認後數據就永久更改,不能回滾了' MariaDB [hellodb]> COMMIT;
    2. 人爲定義啓動事務(如下3個命令均可以)

      1. BEGIN
      2. BEGIN WORK
      3. START TRANSACTION
    3. 結束事務:

      1. COMMIT:提交
      2. ROLLBACK: 回滾
        注意:只有事務型存儲引擎中的DML語句方能支持此類操做
    4. 事務保存點

      1. SQL關鍵字
        SAVEPOINT identifier
      2. 回滾到保存點語法格式
        ROLLBACK [WORK] TO [SAVEPOINT] identifier
      3. 刪除保存點
        RELEASE SAVEPOINT identifier
      4. 示例:事務在執行增刪改時增長保存點,當執行回滾操做時,能夠只撤銷一部分
                 
                 
                 
                 
                 
        • 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
        '1. 開啓事務' MariaDB [hellodb]> BEGIN; Query OK, 0 rows affected (0.00 sec) 2. '修改students表stuid爲23的學員classid編號爲15' MariaDB [hellodb]> UPDATE students SET classid=15 WHERE stuid=23; 3. '設置保存點,命名爲sp23' MariaDB [hellodb]> savepoint sp23; 4. '修改同上' MariaDB [hellodb]> UPDATE students SET classid=16 WHERE stuid=24; 5. '設置保存點' MariaDB [hellodb]> savepoint sp24; 6. '修改同上' MariaDB [hellodb]> UPDATE students SET classid=17 WHERE stuid=25; 7. '查看修改後的數據,以下所示' MariaDB [hellodb]> SELECT * FROM students; | 23 | Ma Chao | 23 | M | 15 | NULL | | 24 | Xu Xian | 27 | M | 16 | NULL | | 25 | Sun Dasheng | 100 | M | 17 | NULL | 8. '回滾到保存點sp24,能夠看到只有25號學員信息返回原狀態' MariaDB [hellodb]> ROLLBACK TO sp24; | 23 | Ma Chao | 23 | M | 15 | NULL | | 24 | Xu Xian | 27 | M | 16 | NULL | | 25 | Sun Dasheng | 100 | M | NULL | NULL | 9. '回滾到保存點sp23,能夠看到23號學員修改信息沒有改變' MariaDB [hellodb]> ROLLBACK TO sp23 ; | 23 | Ma Chao | 23 | M | 15 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | Sun Dasheng | 100 | M | NULL | NULL |
  • 事務隔離級別

事務隔離級別 髒讀可能性 不可重複讀可能性 幻讀可能性 加鎖讀
讀未提交(read-uncommitted)
不可重複讀(read-committed)
可重複讀(repeatable-read)
串行化(serializable)
  1. 各級別說明,從上至下更加嚴格

    1. READ UNCOMMITTED
      可讀取到未提交數據,產生髒讀(讀到的數據是一個沒有肯定的結果,可能會產生誤讀)
    2. READ COMMITTED
      可讀取到提交數據,但未提交數據不可讀,產生不可重複讀,便可讀取到多個提交數據,致使每次讀取數據不一致(例如A用戶(執行修改)與B用戶同時執行事務,B用戶在事務生命期內(大於A用戶事務生命期)能夠讀取到A用戶修改提交前原始一致數據data1,A用戶提交後新一致數據data2,中間的髒數據不能讀取)
    3. REPEATABLE READ
      可重複讀,屢次讀取數據都一致,產生幻讀,即讀取過程當中,即便有其它提交的事務修改數據,仍只能讀取到未修改前的舊數據。此爲MySQL默認設置
      (例如例如A用戶(執行修改)與B用戶同時執行事務,B用戶在事務生命期(大於A用戶事務生命期)內讀取到的數據始終爲data1,A用戶修改後的數據在此事務生命期內不會顯示)
    4. SERIALIZABILE
      可串行化,未提交的讀事務阻塞修改事務,或者未提交的修改事務阻塞讀事務,致使併發性能差。處於阻塞狀態的操做會有一個等待時間(可經過變量修改),超過期間沒有執行,就會撤銷操做
      1. 阻塞狀態等待時間相關變量爲innodb_lock_wait_timeout
      2. 顯式加鎖等待時間變量爲 wait_timeout
  2. 指定事務隔離級別:
    服務器變量tx_isolation指定,默認爲REPEATABLE-READ,可在GLOBAL和SESSION級進行設置

    1. 官方tx_isolation選項說明
           
           
           
           
           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      tx_isolation Description: The transaction isolation level. See also SET TRANSACTION ISOLATION LEVEL. Commandline: --transaction-isolation=name <==做爲服務器選項名字不一樣 Scope: Global, Session Dynamic: Yes Type: enumeration Default Value: REPEATABLE-READ Valid Values: READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE
    2. 當作變量臨時修改
           
           
           
           
           
      • 1
      SET tx_isolation='READ-UNCOMMITTED|READ-COMMITTED|REPEATABLE-READ|SERIALIZABLE'
    3. 服務器選項中指定
           
           
           
           
           
      • 1
      • 2
      • 3
      [root@hai7-8 ~]$vim /etc/my.cnf [mysqld] transaction-isolation=SERIALIZABLE

5 日誌

沒有特殊需求,勁量少的啓用非默認設置,多少都會拖慢速度

  1. 事務日誌 transaction log
  2. 中繼日誌 reley log
  3. 錯誤日誌 error log
  4. 通用日誌 general log
  5. 慢查詢日誌 slow query log
  6. 二進制日誌 binary log

5.1 事務日誌(transaction log)

保存事務在執行中的操做,事務型存儲引擎自行管理和使用

  • 特徵

    1. 預寫式日誌 (write ahead logging)
      事務日誌的寫入類型爲「追加」,所以其操做爲「順序IO」,因此被稱爲預寫式日誌;
    2. 寫入速度快
      當執行大量寫操做時,速度會比直接寫入數據庫快
      緣由是,事務日誌是追加寫入,而數據庫是隨機寫入,須要尋址。在事務提交時,因爲是一次寫入,速度要比寫一條提交一條快不少,與BUFFER原理相同。缺點是事務執行時會加鎖,有可能影響併發性。
    3. 日誌的寫入要早於寫入數據庫
  • 事務日誌文件

    1. 默認存放在mysql的家目錄下,文件名爲ib_logfile0, ib_logfile1
    2. 事務日誌默認固定大小爲5M,寫滿就會覆蓋以前的數據
    3. 修改存放路徑
      不支持動態更改,須要修改配置文件重啓服務
      須要注意的是新指定的存放目錄權限問題,要保證mysql有寫權限
           
           
           
           
           
      • 1
      • 2
      • 3
      [root@hai7-8 ~]$vim /etc/my.cnf [mysqld] innodb_log_group_home_dir=/data/mysqllogs
  • Innodb事務日誌相關配置:

       
       
       
       
       
    • 1
    • 2
    • 3
    • 4
    show variables like '%innodb_log%'; innodb_log_file_size 5242880 <==每一個日誌文件大小 innodb_log_files_in_group 2 <==日誌組成員個數 innodb_log_group_home_dir ./ <==事務文件路徑,表示在mysql的家目錄下文件名爲ib_logfile0|1默認大小爲5M

5.2 中繼日誌(relay log)

主從複製架構中,從服務器用於保存從主服務器的二進制日誌中讀取的事件

5.3 錯誤日誌

  • 記錄內容
    1. mysqld啓動和關閉過程當中輸出的事件信息
    2. mysqld運行中產生的錯誤信息
    3. event scheduler運行一個event時產生的日誌信息
    4. 在主從複製架構中的從服務器上啓動從服務器線程時產生的信息
  • 錯誤日誌相關配置
       
       
       
       
       
    • 1
    • 2
    • 3
    SHOW GLOBAL VARIABLES LIKE 'log_error' log_error=/PATH/TO/LOG_ERROR_FILE <==錯誤文件路徑 log_warnings=1|0 <==是否記錄警告信息至錯誤日誌文件,默認值1

5.4 通用日誌

  • 記錄內容
    記錄對數據庫的通用操做,包括錯誤的SQL語句,記錄較頻繁,按需開啓
  • 通用日誌相關設置
    1. 啓用禁用通用日誌
      general_log=ON|OFF
    2. 通用數據庫文件路徑,默認在mysql家目錄下文件爲centoos7.log
      general_log_file=HOSTNAME.log
    3. 修改通用日誌的保存類型
      文本文件很差管理,能夠考慮修改成table,修改後放在數據庫系統庫mysql內,以後能夠經過-e選項導出爲文本
      log_output=TABLE|FILE|NONE

5.5 慢查詢日誌

  • 功能
    定義一個閾值,來觸發慢查詢日誌,超過此閾值將記錄在慢查詢日誌中
  • 相關設置
    1. 開啓或關閉慢查詢(global),開啓後自動在mysql家目錄下生成centos7-slow.log文件
      slow_query_log=ON|OFF
    2. 慢查詢的閥值,單位秒(global|session)
      long_query_time=N
           
           
           
           
           
      • 1
      MariaDB [hellodb]> SET long_query_time=5;
    3. 重命名慢查詢日誌文件
      slow_query_log_file=HOSTNAME-slow.log
    4. 超過閾值,默認記錄類型(查增刪改都會記錄)
           
           
           
           
           
      • 1
      log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
    5. 不使用索引或使用全索引掃描,不管是否達到慢查詢閥值的語句是否記錄日誌,默認OFF,即不記錄
      log_queries_not_using_indexes=ON
    6. 多少次查詢才記錄,mariadb特有
      log_slow_rate_limit = 1
    7. 記錄內容
      log_slow_verbosity= Query_plan(查詢計劃),explain(執行過程)
    8. 同slow_query_log 新版已廢棄,5.129爲了兼容留着,mariadb10.0/mysql5.6.1已刪除
      log_slow_queries = OFF

5.6 二進制日誌

  • 功能
    記錄致使數據改變或潛在致使數據改變的SQL語句,經過「重放」日誌文件中的事件來生成數據副本,也就是將二進制文件中的SQL語句從新執行一次,未來能夠用二進制日誌來實現主從複製
    -特徵

    1. 記錄已提交的日誌
    2. 不依賴於存儲引擎類型
    3. 不斷追加,不會覆蓋以前記錄
    4. 二進制日誌屬於歸檔日誌,能夠用來還原數據
  • 優化建議
    建議二進制日誌和數據文件分開存放,不至於一塊兒丟失,有還原機會

  • 二進制日誌記錄格式

    1. 基於「語句」記錄(statement),
      1. 記錄SQL語句,默認模式
        例如執行UPDATE students SET age=10;沒有限定條件,實際修改的是所有記錄好比25條,記錄模式爲語句記錄,將只記錄此條SQL語句
      2. 缺陷:若是SQL語言執行時使用的是變量,例如now(),後期還原時此記錄將與原紀錄不符
    2. 基於「行」記錄(row)
      記錄數據,日誌量較大,承上所述,記錄模式選擇爲行記錄,將記錄25條修改記錄
    3. 混合模式(mixed)
      讓系統自行斷定該基於哪一種方式進行,建議選擇mixed。10.2.4版本以後默認爲mixed
  • 查看默認二進制記錄格式
    show variables like 'binlog_format';

  • 二進制日誌文件的構成

    1. 日誌文件:
      mysql|mariadb-bin.文件名後綴,二進制格式,初始值245字節大小
      如: mariadb-bin.000001
    2. 索引文件:
      mysql|mariadb-bin.index,文本格式,記錄當前有效的二進制文件是誰
  • 二進制日誌相關的服務器變量:

    1. 開啓二進制日誌文件,兩項都開啓才能夠開啓二進制日誌功能
      1. 是否記錄二進制日誌,默認ON,支持熱修改
        sql_log_bin=ON|OFF
      2. (只讀,只能在配置文件中設置)指定文件位置;默認OFF,表示不啓用二進制日誌功能
        log_bin=/PATH/BIN_LOG_FILE
               
               
               
               
               
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        [root@hai7-8 ~]$vim /etc/my.cnf [mysqld] log-bin '若是寫成log-bin=on,表示啓用並定義生成的二進制文件名前綴爲on.,不寫表示啓用,文件名由系統自定義' log-bin=/data/mysqlbin/mysql-bin '能夠指定路徑,修改目錄mysql要具備寫權限,寫一種就好'
    2. 二進制日誌記錄的格式,默認STATEMENT
      binlog_format=STATEMENT|ROW|MIXED
    3. 單個二進制日誌文件的最大致積,到達最大值會自動滾動,默認爲1G
      max_binlog_size=1073741824
      說明:文件達到上限時的大小未必爲指定的精確值
    4. 設定是否啓動二進制日誌即時同步磁盤功能,默認0,由操做系統負責同步日誌到磁盤,即時寫入,或者緩存起來一塊兒寫入
      sync_binlog=1|0
    5. 二進制日誌能夠自動刪除的天數。 默認爲0,即不自動刪除
      expire_logs_days=N
  • 二進制日誌管理

    1. 查看mariadb自行管理使用中的二進制日誌文件列表,及大小
      SHOW {BINARY | MASTER} LOGS
    2. 查看使用中的二進制日誌文件,與SHOW LOGS顯示內容相似,更詳細
      SHOW MASTER STATUS
           
           
           
           
           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      MariaDB [hellodb]> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000010 | 2185 | | | +------------------+----------+--------------+------------------+ `position`:表示位置,和數據大小同樣,表示後續文件將從這個位置開始
  • 查看二進制文件中的指定內容

    1. 語法格式
      SHOW BINLOG EVENTS [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count]
    2. 說明
      1. LIMIT:限定查看後續的第幾條記錄
      2. FROM pos:從哪一個位置開始,pos就是上例中的position
    3. 示例
           
           
           
           
           
      • 1
      SHOW BINLOG EVENTS IN 'mysql-bin.000001' from 2106 limit 2,3
  • 二進制日誌事件的格式:

       
       
       
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    # at 328 #151105 16:31:40 server id 1 end_log_pos 431 Query thread_id=1 exec_time=0 error_code=0 use `mydb`/*!*/; SET TIMESTAMP=1446712300/*!*/; CREATE TABLE tb1 (id int, name char(30)) <==事件內容 /*!*/;
    1. 事件發生的日期和時間:151105 16:31:40 151105爲年月日
    2. 事件發生的服務器標識:server id 1
    3. 事件的結束位置:end_log_pos 431
    4. 事件的類型:Query
    5. 事件發生時所在服務器執行此事件的線程的ID:thread_id=1
    6. 語句的時間戳與將其寫入二進制文件中的時間差:exec_time=0
    7. 錯誤代碼:error_code=0
    8. GTID:Global Transaction ID,mysql5.6以mariadb10以上版本專屬屬性,保證全部服務器上發生的日誌都有惟一的編號
  • 清除指定二進制日誌:

    1. 語法格式
      PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
    2. 示例
      1. 刪除5以前的日誌,5保留
               
               
               
               
               
        • 1
        MariaDB [hellodb]> PURGE BINARY LOGS TO 'mysql-bin.000005';
      2. 刪除2017-01-23以前的日誌
               
               
               
               
               
        • 1
        PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';
  • 刪除全部二進制日誌,index文件從新記數
    日誌文件從#開始記數,默認從1開始,通常是master第一次啓動時執行,MariaDB10.1.6開始支持TO #
    RESET MASTER [TO #]

  • 切換日誌文件,生成的日誌和原日誌文件都是有效的

    1. SQL語句
      FLUSH LOGS
    2. 應用場景
      將舊文件備份後,生成新的日誌文件,讓以後的日誌都存放在新的文件中

6. 命令行專用二進制工具 mysqlbinlog

  • 命令格式
    mysqlbinlog [OPTIONS] log_file…

  • OPTIONS

    1. –start-position=#:指定開始位置
    2. –stop-position=#:指定結束位置
    3. –start-datetime=:指定開始時間
    4. –stop-datetime=:指定結束時間
      時間格式:YYYY-MM-DD hh:mm:ss
    5. –base64-output[=name]:以base64編碼顯示
  • 示例

    1. 設置起始位置和結束位置查看日誌內容
           
           
           
           
           
      • 1
      mysqlbinlog --start-position=6787 --stop-position=7527 /var/lib/mysql/mariadb-bin.000003
    2. 設置起始位置和結束位置查看日誌內容
           
           
           
           
           
      • 1
      mysqlbinlog --start-datetime="2018-01-30 20:30:10" --stop-datetime="2018-01-30 20:35:22" /var/lib/mysql/mariadb-bin.000003
    3. 以base64格式輸出顯示
           
           
           
           
           
      • 1
      mysqlbinlog /var/lib/mysql/mariadb-bin.000003 --start-datetime="2018-01-30 20:30:10" --stop-datetime="2018-01-30 20:35:22" --base64-output
    4. 二進制日誌以行格式保存日誌,默認爲base64顯示,將其以文本格式顯示
           
           
           
           
           
      • 1
      mysqlbinlog /var/lib/mysql/mariadb-bin.000003 -v
  • 利用二進制文件恢復數據

    1. 導出丟失數據對應的二進制文件,好比對應的二進制文件位置在2165,文本或者base64編碼均可以識別的
           
           
           
           
           
      • 1
      [root@hai7-8 ~]$mysqlbinlog /var/lib/mysql/mariadb-bin.000003 --start-datetime=2165 > /data/text.sql
    2. 記錄的自己就是SQL語句,因此能夠將其直接導入mysql丟失數據的數據庫中
           
           
           
           
           
      • 1
      [root@hai7-8 ~]$mysql hellodb < /data/test.sql
</div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7f770a53f2.css" rel="stylesheet">
            </div>
相關文章
相關標籤/搜索