稀にですが、WordPressのDBを直接更新したい場合があります。
DBの直接更新はリスクがあり、正常に動かなくなる可能性も否定できません。
トラブル時にはDBをバックアップから復元する、という情報がありますが、これでは不十分だと思います。
DBを直接更新する場合は、「トランザクション」を利用しましょう。
データを書き換えることなく、結果をシミュレーションすることができます。
一発勝負、出たとこ勝負はしないようにしましょう。
こんな方におすすめ
- WordPressで直接DBを更新したい方
- PHPMyAdminなどで、トランザクションを使ったことがない方
- WordPress(DB)の容量が大きい方
バックアップは最後の備え。作業前には必須!
トランザクションを使う場合も、バックアップは必須です。
趣旨としては、データを書き換える前に結果を確認しよう!ということです。
誤解を与えないため、最初に言及しておきます。
取得しておくバックアップについて
トランザクションの応用でシミュレーションができます。
あくまで結果の確認だけであり、想定自体が間違っている場合は防げません。
バックアップ自体は必要であると覚えておきましょう。
DB
更新する対象なので、確実に取っておきましょう。
万が一の際には、バックアップから復元(インポート)で更新前の状態に戻します。
そうならないために、トランザクションを活用するということですね。
サイトデータ
書き換える直接の対象ではないので、バックアップ推奨です。
ただ、バックアップにはかなり時間がかかる可能性があります。
サーバーなどで自動取得データがあれば、優先度は低くなります。
いずれにしても、当日データがないなら絶対に取っておくべきです。
トランザクションを使ってみよう!
トランザクションとは?
何度も登場している「トランザクション」について、ざっくり解説します。
直訳すると、「商取引」などです。
DBでは、関連する処理のひとかたまりを一つのトランザクションとします。
そのかたまり毎に、正常終了なら結果を反映、異常が発生したら結果を破棄します。
尚、度々”シミュレーションができる機能”としていますが、正確には巻き戻し処理です。
例: ひとかたまりの処理ってどういうの?
実際にはもっと複雑なはずですが、簡単な例を二つほど紹介します。
例1: 配送
配送は、送り主から受け取り主まで届いて初めて完了です。
「送る」と「受け取り」が切り離されていると、配送トラブルなどがあっても、送り主側は配送完了になってしまいます。
例2: 銀行取引
銀行の振込手続きなどは、より顕著かもしれません。
送金と着金側が切り離されている場合、お金が消失する可能性があります。
送金側が正常、着金側が異常で受け取れない場合は、事実上お金の消失が発生するわけです。
信用創造で電子データ頼みの社会では、かなり致命的なトラブルになりかねません。
実は簡単!トランザクションの実行方法!
トランザクションは、記述方法が非常に簡単です。
- 「BEGIN」でトランザクションを開始
- トランザクションの内容を「実行」したい場合は、終了位置で「COMMIT」
- トランザクションの内容を「破棄(巻き戻し)」したい場合は、終了位置で「ROLLBACK」
コードの概要
BEGIN;
# 確認したい処理
ROLLBACK;
# または
COMMIT;
WordPressでトランザクションを使ってDBを書き換えてみよう!
実際にWordPress環境で、サイトのURLを書き換えてみます。
※補足: 「wp_options」テーブルの、「option_name」が「siteurl」のレコードが対象です。
変更をロールバック(巻き戻し)した場合のコードと実行結果の例
コード
# トランザクションを開始
BEGIN;
# 「siteurl」の値を更新
UPDATE `wp_options` SET `option_value` = 'new url'
WHERE `option_name` = 'siteurl';
# 更新後の結果を表示
SELECT *
FROM `wp_options`
WHERE `option_name` = 'siteurl';
# 変更の巻き戻し
ROLLBACK;
# 巻き戻し後の結果(変更前の値)
SELECT *
FROM `wp_options`
WHERE `option_name` = 'siteurl';
一つ目の表示結果が、下図になります。
更新分で設定した「new url」になっています。
そして、二つ目の表示結果が、下図になります。
「localhost」のurlになっており、先に設定した値が破棄されたことが分かります。
変更をコミット(正常終了)した場合のコードと実行結果の例
コード
# トランザクションを開始
BEGIN;
# 「siteurl」の値を更新
UPDATE `wp_options` SET `option_value` = 'new url'
WHERE `option_name` = 'siteurl';
# 更新後の結果を表示
SELECT *
FROM `wp_options`
WHERE `option_name` = 'siteurl';
# (※差分はここだけ)正常終了して結果を反映
COMMIT;
# 更新結果の確認
SELECT *
FROM `wp_options`
WHERE `option_name` = 'siteurl';
一つ目の表示結果が、下図になります。
先ほどと同じく、更新分で設定した「new url」になっています。
そして、二つ目の表示結果が、下図になります。
変更は破棄されず、更新後の値が維持されています。
ポイント
まずは本番更新前に、ロールバックで表示を確認。
動作確認後に、結果をコミット。
これで、DB更新の一発勝負を避けることができる!
PHPMyAdminでコミットもロールバックもしない場合は、ロールバックが適用される
デフォルトの設定では、トランザクションを終了し忘れると自動でロールバックが発生します。
SQLによって仕様が異なるので、言語の仕様は確認しておきましょう。
ちなみに、PostgreSQLも暗黙的にロールバックを実行します。
MySQLの仕様
デフォルトでは、MySQL は自動コミットモードが有効になった状態で動作します。 つまり、特にトランザクション内にない場合、各ステートメントは START TRANSACTION および COMMIT で囲まれているかのようにアトミックです。 ROLLBACK を使用して効果を元に戻すことはできませんが、ステートメントの実行中にエラーが発生した場合、ステートメントはロールバックされます。
START TRANSACTION を使用すると、そのトランザクションを COMMIT または ROLLBACK で終了するまで、自動コミットは無効のままになります。 そのあと、自動コミットモードはその以前の状態に戻ります。
PostgreSQLの仕様
トランザクション処理の途中でコミットをおこなわない(アリスの口座残高が足りなかったような場合)と判断したばあいは COMMIT ではなく ROLLBACK を使用して、行なわれたすべての更新を破棄します。
MySQL公式: https://dev.mysql.com/doc/refman/8.0/ja/commit.html
PostgreSQL公式: https://www.postgresql.jp/document/7.2/tutorial/tutorial-transactions.html
まとめ: 書き換え前にシミュレーションをして、DBを安全に更新しよう!
トランザクション(ロールバック)を使うと、値を更新せずに結果を確認できます。
特にPHPMyAdminなどのツールでは、何行更新したかが画面で確認可能です。
数が合わない、表示が予想と違うなど、トラブル解決に活用できます。
DBを直接更新する場合には、ぜひ活用しましょう