type
status
date
slug
summary
tags
category
icon
password
  • 支援的 rewrite 的語句
    • MySQL 8.0.12 之前:只支援 SELECT 語句
    • MySQL 8.0.12 之後:支援 SELECT, INSERT, REPLACE, UPDATE, DELETE 語句
    • view definitions、stored programs 內相應的語句不會被 rewrite
  • 從 MySQL 8.0.31 開始當 rewriter_enabled_for_threads_without_privilege_checks = OFF 時,具有 SKIP_QUERY_REWRITE 權限的 USER 執行語法時不會受到 rewrite,適合用於 mysqldump、mysqladmin、replication 等 USER。
 

安裝與開啟

/usr/share/ 內有 install_rewriter.sqluninstall_rewriter.sql 兩個檔案用來安裝或移除 rewriter plugin。
注意:安裝了 Rewriter 插件後,即使在禁用時也有額外的開銷,因此建議在需要的時候才安裝。
安裝之後可以透過在設定檔添加設定,或者是直接 SET 來開啟 rewrite plugin:

設定

新增 pattern

透過將規則寫入到 query_rewrite.rewrite_rules 來新增設定,新增設定時 pattern 和 prepare 語句的格式相同:
新增規則後需要調用 flush_rewrite_rules() 來將設定加載到緩存中:
當規則順利加載到內存中時會對我們寫入的 pattern 進行 normalized 並更新 normalized_pattern 欄位,另外也會計算 digest(摘要) 的 hash 值更新 pattern_digest 欄位:

關閉 pattern 的運作

關於 pattern_database

Rewrite 插件在寫入規則時,當 pattern 語句中包含 table 時需要包含 database 名稱,如果未指定 database 名稱則必須寫入 pattern_database 欄位,否則會引發錯誤:
Rewrite 插件
  • 如果未指定 pattern_database ,則表示 pattern 語句必須包含 database ,因此只有當語句和 pattern 完全相同時才會匹配:
    • 如果指定 pattern_database,當 default database 和 pattern_database 相同時語句才會匹配:
       
       

      如何匹配

       
      1. 當收到語句時會計算 語句的 digest(摘要) hash 值,這會拿來和 pattern_digest 來比較,用來快速判斷語句是否相同。
      1. 當 語句 和 pattern 的 digest(摘要) hash 值相同時,則會比較 normalized 後的 語句 和 pattern 是否匹配。
      1. 如果 normalized 後的 語句 和 pattern 匹配時,則會完整的比較 語句 和 pattern 中的每個字,而其中 pattern 中的 ? 匹配任何文字值,這包含匹配 prepare 語句中的 ?。
      如果多個規格匹配同一個語句,會無法確認是應用哪一種規則的語句
       

      Rewrite prepare 語句

      prepare 語句是在被解析時 (也就是 prepare 時) 重寫,而不是執行的時候。
      Rewrite pattern 中的 ? 可以匹配任何文字值,也能匹配 prepare 語句中的佔位符 ?,假設在規格中新增了以下 pattern:
      prepare 語句
      是否可以匹配
      PREPARE s AS 'SELECT 3, 3’
      Yes
      PREPARE s AS 'SELECT ?, 3’
      Yes
      PREPARE s AS 'SELECT 3, ?’
      No
      PREPARE s AS 'SELECT ?, ?’
      No

      參考