Mysql

防止複制 ALTER 命令

  • August 11, 2020

我將 MariaDB 10.0 多源複製用於特定案例。

出於安全原因,我想阻止 master 上的 ALTER 命令複製(例如CREATE, ALTER, DROP…)任何使用者執行這些命令(甚至是 root),但當然讓SELECT, INSERT, UPDATE,DELETE命令複製….

我不想SET SQL_LOG_BIN=0|1在客戶端使用。事實上,我從不想複製模式修改。

在實踐中,我希望我可以撤銷對我的複制使用者(目前具有 REPLICATION SLAVE 權限)的更改權限

有沒有辦法做到這一點?

編輯 2018-02-19

由於我的要求對某些讀者來說似乎是無稽之談,因此我提供了有關此案例的一些附加資訊。

我使用 BLACKHOLE 儲存引擎創建了一個(或多個)帶有表的 MariaDB 代理數據庫。所以數據不會儲存在這個代理伺服器上,但 binlogs 是。

我有其他 MariaDB 伺服器執行相同的數據庫模式,但使用 INNODB 儲存引擎使用 MariaDB 多源複製從代理伺服器複製數據。

例如,在代理伺服器上,我可以安全地重新創建帶有CREATE OR REPLACE TABLE mytable (id int) ENGINE=BLACKHOLE語句的表模式,因為其中沒有儲存數據。

但是這種語句不能在“從屬”(它們不是你注意到的真正的從屬)上按原樣執行,因為它們必須保留在其原始儲存引擎或它們在表級別可能具有的任何其他選項中。

我可以通過在執行命令之前發出 a 來做到這一點SET SQL_LOG_BIN=0,但我正在尋找一種方法來確保我不會破壞奴隸,以防我忘記這樣做。

方法#1

最簡單的做法是撤銷所有使用者的ALTERDROPCREATE,除了root

UPDATE mysql.user SET alter_priv='N',drop_priv='N',create_priv='N' WHERE user <> 'root';
UPDATE mysql.db   SET alter_priv='N',drop_priv='N',create_priv='N' WHERE user <> 'root';
FLUSH PRIVILEGES;

方法#2

你說你不想發行

SET sql_log_bin = 0;

在客戶端。一種非常冒險的方法是使用儲存過程來執行您的ALTER TABLE命令。然後,您可以SET sql_log_bin = 0;在儲存過程中申請。實際上,這發生在伺服器端。

DELIMITER $$

DROP PROCEDURE IF EXISTS `Local_Alter_Table` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `Local_Alter_Table`
(
   SQLStatement VARCHAR(2048)
)
BEGIN

   SET sql_log_bin = 0;

   SET @sql = SQLStatement;
   PREPARE s FROM @sql;
   EXECUTE s;
   DEALLOCATE PREPARE s;

   SET sql_log_bin = 1;

END $$

DELIMITER ;

然後,要求使用者執行

CALL Local_Alter_Table('ALTER TABLE ...');

試一試 !!!

相反,強制使用者使用儲存過程來執行任何CREATE/DROP命令。從GRANTing CREATE/DROP不允許使用者開始。在 Master vs Blackhole vs Slave 上有不同版本的 SP。差異包括適當的組合

  • 0 或 1 代表SQL_LOG_BIN (也許這是不必要的)
  • 執行或跳過CREATE/DROP.

創建 SP as rootand haveSECURITY DEFINER以便 SP 可以實際執行 DDL,即使使用者不能。

引用自:https://dba.stackexchange.com/questions/116608