exceedone / exment

Exment is open source software for managing information assets on the Web. / Exmentは、情報資産をWeb上で管理するための、オープンソースソフトウェアです。
https://exment.net/docs/#
GNU General Public License v3.0
269 stars 68 forks source link

Exment環境レストア時にSQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraintのエラーが出る #1336

Closed fleming35800 closed 1 year ago

fleming35800 commented 1 year ago

Describe the bug / バグの説明

A clear and concise description of what the bug is. / バグの内容のかんたんな説明を記載してください。 Xserverの共有サーバーにExmentの環境を展開しています。 外部トラフィックの影響か時間帯により著しく重くなってしまうことがある為、マネージド専用サーバーに環境を展開しようとしています。 何も設定していないサラのExmentの環境は構築できたのですが、社内で使用しているExmentの環境をレストアしようとするとエラーが出ます。 Xserverの共有サーバーはデータベースがMariaDBですが、マネージドサーバーはMySQLになっております。 laravelをmigrateしようとする時に主に出ることのあるエラーのようで同じようなエラーのようでして・・・同じような内容で悩んでいるかたいませんでしょうか? 解決方法等ご存じでしたらご教授いただけませんか。

To Reproduce / 再現手順

Please describe the reproduction procedure in as much detail as possible. / 再現手順を、可能な限り詳細に記載してください。 xserverの共有サーバーのExmentのバックアップファイルをxserverのマネージドサーバーへ展開する。 php 以下コマンド実行。 php artisan exment:restore [バックアップファイル名]

Version / 発生バージョン

Please describe version. / ご利用のバージョンを記載してください。 v5.0.7

Error log / エラーログ

If possible, paste error log. Log's path is "storage/logs/laravel.log". / 可能であれば、ログを貼り付けてください。ログのパスは"storage/logs/laravel.log"です。 以下エラーが出ています。 yntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (xb576741_exment.custom_copy_columns, CONSTRAINT custom_copy_columns_ custom_copy_id_foreign FOREIGN KEY (custom_copy_id) REFERENCES xb576741_exment.custom_copies (id)) (SQL: truncate table custom_copies) {"userId":1,"exception":"[object] (Illuminate\Database\QueryException(code: 4200 0): SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (xb576741_exment.custom_copy_columns, CONSTRAINT custom_copy_columns_custom_copy_id_foreign FOREIGN KEY (custom_copy_id) REFERENCES xb576741_exment.custom_copies (id)) (SQL: truncate table custom_copies) at /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Database/Connection.php :760) [stacktrace]

0 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Database/Connection.php(720): Illuminate\Database\Connection->runQueryCallback('truncate table ...', Array, Object(Closure))

1 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Database/Connection.php(546): Illuminate\Database\Connection->run('truncate table ...', Array, Object(Closure))

2 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3567): Illuminate\Database\Connection->statement('truncate table ...', Array)

3 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/exceedone/exment/src/Database/MySqlConnection.php(280): Illuminate\Database\Query\Builder->truncate()

4 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(469): Exceedone\Exment\Database\MySqlConnection->restoreDatabase('/home/xb576741/...')

5 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(338): Illuminate\Database\DatabaseManager->__call('restoreDatabase', Array)

6 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/exceedone/exment/src/Services/BackupRestore/Restore.php(243): Illuminate\Support\Facades\Facade::__callStatic('restoreDatabase', Array)

7 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/exceedone/exment/src/Services/BackupRestore/Restore.php(73): Exceedone\Exment\Services\BackupRestore\Restore->restoreDatabase()

8 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/exceedone/exment/src/Controllers/BackupController.php(340): Exceedone\Exment\Services\BackupRestore\Restore->execute('20230804125714')

9 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Exceedone\Exment\Controllers\BackupController->import(Object(Illuminate\Http\Request))

10 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction('import', Array)

11 /home/xb576741/xb576741.xbiz.jp/laravel/exment/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Exceedone\Exment\

\Controllers\BackupController), 'import')

fleming35800 commented 1 year ago

こちらの問題自己解決いたしました。 同じことに悩む方はあまりいないのかもしれませんが、覚書も含め今回の原因と解決方法です。 ■原因  SET FOREIGN_KEY_CHECKS=0が効かないことにより、外部キーの成約があるテーブルをtrancateできなくなっていた。  エラー箇所以下ソースの280行目  /vendor/exceedone/exment/src/Database/MySqlConnection.php

■詳細  /vendor/exceedone/exment/src/Database/MySqlConnection.php  の241行目で  \DB::statement('SET FOREIGN_KEY_CHECKS=0;');  しておりこの時点ではFOREIGN_KEY_CHECKS=0になっていると思われる。  レストアしようとしているデータが大きすぎるが故に処理が完了する前にセッションが閉じてしまい、再接続したタイミングでFOREIGN_KEY_CHECKS=1に戻ってしまっていたと思われる。

■対応  かなり無理やりですが問題の280行目の手前に  \DB::statement('SET FOREIGN_KEY_CHECKS=0;');  を挟むことにより現象解決いたしました。  Before  /vendor/exceedone/exment/src/Database/MySqlConnection.php279行目~ if (\Schema::hasTable($table)) { \DB::table($table)->truncate(); }  After if (\Schema::hasTable($table)) { **\DB::statement('SET FOREIGN_KEY_CHECKS=0;');** \DB::table($table)->truncate(); }

自己解決によりクローズさせていただきます。