1. ホーム
  2. データベース
  3. エムエスエル

MySQLスレーブ遅延1列外部キーチェックとセルフインクリメントロック

2022-01-18 22:23:12

MySQLスレーブ遅延外部キーチェックとセルフインクリメントロック

I. 現象

大きな、大きなものを遅らせる。

  • テーブル構造

  • IOなし

  • SQL THREADが100%のCPUを使用

II. pscakサンプリング

サンプリング 30点

  • 外部キーチェック 70

  • セルフインクリメントロックフェッチ30%で

III. 自己増加型ロック獲得ロジック

このロジックは実際には innodb_autoinc_lock_mode パラメータと同じです。

switch (lock_mode) {
    case AUTOINC_NO_LOCKING://innodb_autoinc_lock_mode=2
        /* Acquire only the AUTOINC mutex. */
        dict_table_autoinc_lock(m_prebuilt->table);
        break;

    case AUTOINC_NEW_STYLE_LOCKING: // innodb_autoinc_lock_mode=1 Note that there is no break here, which cleverly completes the logic
        /* For simple (single/multi) row INSERTs, we fallback to the
        old style only if another transaction has already acquired
        the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
        etc. type of statement. */
        if (thd_sql_command(m_user_thd) == SQLCOM_INSERT
            || thd_sql_command(m_user_thd) == SQLCOM_REPLACE) {

            dict_table_t* ib_table = m_prebuilt-> table;

            /* Acquire the AUTOINC mutex. */
            dict_table_autoinc_lock(ib_table);

            /* We need to check that another transaction isn't
            If (dict_table_autoinc_lock(ib_table)); /* We need to check that another transaction isn't already holding the AUTOINC lock on the table.
            if (ib_table->n_waiting_or_granted_auto_inc_locks) {
                /* Release the mutex to avoid deadlocks. */
                dict_table_autoinc_unlock(ib_table);
            } else {
                break;
            }
        }
        /* Fall through to old style locking. */

    case AUTOINC_OLD_STYLE_LOCKING://innodb_autoinc_lock_mode=0 trigger
        DBUG_EXECUTE_IF("die_if_autoinc_old_lock_style_used",
                ut_ad(0););
        error = row_lock_table_autoinc_for_mysql(m_prebuilt); // self-incrementing lock on table on this function

        if (error == DB_SUCCESS) {

            /* Acquire the AUTOINC mutex. */
            dict_table_autoinc_lock(m_prebuilt-> table);
        }
        break;

    default:
        ut_error;
    }



binlogの行のフォーマットで、innodb_autoinc_lock_mode=1はrow_lock_table_autoinc_for_mysqlが自己増加型ロックを追加するトリガーにならないはずです。理由はよくわかりません。現在わかっているのは

  • マスターステートメントモード、スレーブ innodb_autoinc_lock_mode=1 の場合、insert select は確実にトリガーされます。
  • スレーブライブラリ innodb_autoinc_lock_mode=0 ならば間違いなくトリガーされます。

しかし、どちらも満足できない。疑問が残る。

IV. プログラム

外部キーの削除

innodb_autoinc_lock_modeを2に設定すると、論理的にもうrow_lock_table_autoinc_for_mysqlを行わないようにしなければなりません。

この記事 MySQL スレーブ遅延外部キー チェックと自己インクリメント ロックに関する記事はこちら、より関連する MySQL スレーブ遅延外部キー チェックと自己インクリメント ロック内容スクリプト家の過去の記事を検索してくださいまたは次の関連記事を参照してください、今後スクリプト家をよりサポートすることを望む!