2017-06-24 10 views
2

MySQL manual on ALTER FUNCTIONは言う:MySQLのストアドファンクションをアトミックに置き換える方法はありますか?

しかし、あなたはこの文を使用して保存された関数のパラメータまたは本文を変更することはできません。そのような変更を行うには、DROP FUNCTIONとCREATE FUNCTIONを使用して関数を削除して再作成する必要があります。

DROP + CREATEを使用する際の問題は、2つのステートメントの間に関数が存在しない短い時間間隔が存在することです。これが大量のデータベースである場合、これは、このタイムパンで実行中にストアド関数を使用するクエリが失敗することを意味します。

MySQL manual on implicit commitsストレス

のALTER FUNCTIONこと、FUNCTIONおよびDROP FUNCTIONをCREATEも保存された機能

で使用した場合、暗黙的なコミットを引き起こすだから、2つの、問題文をラップするだけには役立ちません。取引で

PostgreSQLはこれに対してCREATE OR REPLACE FUNCTIONを提供しています。 MySQLの問題をどのように解決するのですか?

+1

私はこれが可能であるとは思わない。 –

+0

解決しようとしている問題はわかりませんが、mysqlのストアドファンクションを絶えず削除して再作成する方法は解決できません。私はこれが単なる「アップグレード/メンテナンス中」という質問になることを願っています。そうであれば、トランザクションはジョブを実行する必要があります。また、LOCKを使用してテーブルをロックすることもできます。 – gview

+0

@gview:トランザクションは機能しません。「問題のある2つのステートメントをトランザクションでラップするのは役立たない」を参照してください。 LOCKはテーブルへのアクセスのみを防止するため、関数の実行ではないため、どちらも機能しません。確かにそれはたまにしか起こらないが、それは重い義務のデータベースであり、短時間の間は関数が存在しない間はクエリのエラーを得る余裕がない。 – rtc

答えて

0

トランザクション内でこれらを組み合わせると問題が解決するはずです。 START TRANSACTIONを発行する前に、セッションの開始時にautocommit = 0を設定し、最後にCOMMITを発行する必要があることに注意してください。

+0

私が私の質問で言ったように、「トランザクションで2つの問題のある文を単純に包むことは役に立ちません」。そしてBTW、[START TRANSACTIONを使用する場合、自動コミット= 0に設定する必要はありません](https://dev.mysql.com/doc/refman/5.7/en/commit.html) – rtc

0

これが私のために正常に動作します:

MariaDB [test]> SELECT @@version; 
+----------------+ 
| @@version  | 
+----------------+ 
| 5.5.50-MariaDB | 
+----------------+ 

proc.sql

mysqlの内部
use test; 
START TRANSACTION; 
DROP PROCEDURE IF EXISTS sproc; 
delimiter // 
CREATE PROCEDURE sproc(OUT param1 INT) 
BEGIN 
    SELECT COUNT(*) INTO param1 FROM t1; 
END// 
delimiter ; 
COMMIT; 

mysql -u root -p < proc.sql 
mysql -u root -p < proc.sql 

MariaDB [test]> CALL sproc(@a); 
Query OK, 1 row affected (0.00 sec) 

MariaDB [test]> select @a; 
+------+ 
| @a | 
+------+ 
| 4 | 
+------+ 
1 row in set (0.00 sec) 
+0

これは機能しますが、方法はありませんあなたはそれがそうだと思います。トランザクションを開始しても、DROPとCREATEは現在実行中のトランザクションを暗黙的にコミットするため、アクションはアトミックではありません。 https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html –

+0

@Bill Karwinお気軽にお問い合わせください。問題の懸念を満たすこの問題に対する解決策がないと思われる。 – gview

0

MySQLがサポートしていませんCREATE OR確保するためにFUNCTION、または他の機能をREPLACE関数を置換する原子性。これは少なくとも2005年以来の優れた機能要求でした:https://bugs.mysql.com/bug.php?id=9588これは、いつこの機能を実装するかについての言葉はありません。

CREATE OR REPLACEの機能は、標準SQLではありません。これはPostgreSQLが実装することを決めた標準SQLの拡張です。

新しい関数を別の名前で定義すると、一時的に古い関数と新しい関数の両方が存在する可能性があります。アプリケーションコード(または他のMySQLルーチンのコード)は、新しい関数名を動的に呼び出すように設計する必要があります。

関連する問題