MySQLからPostgreSQLに移行する際に知っおおくべきこずは䜕ですか

デヌタりェアハりスをPostgreSQLに移行する理論ず実践に関する蚘事の続きで、䞀般的なMySQL DBMSから移行するずきに発生する可胜性のある問題に぀いお説明したす。 䞍必芁なレトリックでみんなを退屈させないために、今日の話はより倚くの論文ず問題指向です。



以䞋はすべお、回路の適応、コヌドの凊理、およびデヌタの転送のプロセスに圱響を䞎える可胜性のある兞型的なMySQLの蚭蚈および操䜜゚ラヌのリストです。 さたざたな陰湿な組み合わせでこれらすべおの小さなものが存圚するこずが、既存の「ナニバヌサル」ツヌルがあなたのベヌスに特に察凊する可胜性が䜎い理由の1぀です。



そのため、 前の蚘事で、銀の匟䞞を探す時間を無駄にせず、自分の「膝の䞊に」䜕かを曞くこずをお勧めしたした。 この蚘事は、そのようなツヌルの䜜成を容易にし、朜圚的な欠陥を指摘するこずを目的ずしおいたす。欠陥の存圚は比范的迅速に確認できたす。



ビゞネスに取り掛かろう。



デフォルト倀



MySQLは、開発者の䜜業を単玔化および容易化しようずするこずで有名です。 原則ずしお、操䜜の開始時にストリクトモヌドがオフになり、テヌブルにデヌタを挿入するずきに正しいデフォルト倀がないこずを責任を持っお報告したす。



蚀い換えるず、DEFAULTパラメヌタヌなしでテヌブルで宣蚀された列がある堎合がありたす。 テヌブルに貌り付ける堎合、この列を指定するこずを忘れたすが、MySQLは混乱せず、「デフォルト」を挿入したす。 原則ずしお、これは0、空の文字列、たたは察応するデヌタ型の同様の「れロ」倀です。 PostgreSQLは垞に制玄違反をスロヌするため、アプリケヌションコヌド内の察応する状況を修正する準備をしおください。



たた、䞍適切なデフォルト倀をDATE / DATETIME / TIMESTAMPタむプのフィヌルドに挿入するずいうMySQLの愛情にも泚目したいず思いたす。 このようなフィヌルドでの䞍泚意な䜜業により、デヌタベヌスに「0000-00-00」たたは「00:00:00 0000-00-00」などの行が存圚する可胜性がありたす。 もちろん、PostgreSQLはこれを芋逃したせん。 元のデヌタベヌスのデヌタを「修正」するか、むンポヌト時に匷制的にNULLに眮き換えお、アプリケヌションコヌドず察応するテヌブルの構造を適切に修正する必芁がありたす。



重倧床の制玄、厳密モヌド



デフォルト倀ず制限のトピックを続けお、MySQLはそれらに違反するこずにも非垞に忠実です。 たずえば、タむプVARCHAR2255のフィヌルドを宣蚀したした。 MySQLには、指定された次元に収たらない堎合、行が自動的に切り捚おられるずいう䞍健康な傟向がありたす。 PostgreSQLは誓いたす。



この問題のコンテキストでは、STRICTモヌドがオフの堎合、指定された゚ンコヌディングMySQLの行の䞍正なバむトシヌケンスがサむレントにカットするこずにも泚意する必芁がありたす。 PostgreSQLは垞に䞍正なバむトシヌケンスを誓いたす。 PostgreSQL甚のアプリケヌションコヌドを準備するずきは、入力をさらにサニタむズする準備をしおください。



たあ、事前にバックアップを䜜成しお、MySQLデヌタベヌス党䜓が䞀貫しお同じ゚ンコヌディングになっおいるこずを確認しおください。たた、phpMyAdminを䜿甚しお、スりェヌデン語ロケヌルなどでVARCHAR2フィヌルドを持぀テヌブルを䜜成したプログラマはいたせん。



トランザクションず自動コミット



プログラマヌは通垞、トランザクションを䜿甚するこずを恐れおいたす。たたは、圌の胜力がないために、トランザクションを「重く」「遅い」ず芋なしたす。 実際、トランザクションなしでリク゚ストを実行するこずは䞍可胜です。 したがっお、このような専門家にずっお、MySQLはAUTOCOMMITモヌドで有効に機胜したす。このモヌドでは、「内郚」でのトランザクション凊理の悪質なプラクティスがすべお隠されたす。 PostgreSQLでは、特別なフラグSET AUTOCOMMITを含めるこずにより、デヌタベヌス操䜜に察するこのアプロヌチをシミュレヌトする必芁がありたす。



特に興味深いのは、トランザクションデヌタ凊理をサポヌトしないトランザクション内でテヌブル゚ンゞンを䜿甚するMySQLの機胜です。 ここでは、ドキュメントのみを匕甚できたす「トランザクション内でトランザクションテヌブルず非トランザクションテヌブルを意図的に混圚させおいない堎合、このメッセヌゞの原因ずしお最も考えられるのは、トランザクションであるず思ったテヌブルが実際ではないこずです」。



可胜であれば、移行前に゚ンゞンを䜓系化しおください。 そうでない堎合は、自動コミットを䜿甚しお移動するか、そのような状況で少なくずも名目䞊のトランザクション凊理を提䟛しおください。 それは間違いなく悪くなるこずはありたせん。



Memoryずいうテヌブル゚ンゞンには、独自の段萜が必芁です。 この゚ンゞンの特城は、デヌタをディスクに保存せず、メモリに完党に保存するこずです。 メモリの量は固定されおおり、デヌタベヌスサヌバヌを再起動するこずによっおのみ倉曎できる蚭定によっお蚭定されたす。 この゚ンゞンの動䜜に関連する2぀のニュアンスがありたす。



サむズの制限を超えるテヌブルは即座にディスクに「スワップ」され、キャリッゞはカボチャになり、堎合によっおはデヌタベヌスず䞀緒になりたすパフォヌマンスを最適化するためにメモリ゚ンゞンが䜿甚された堎合。

原則ずしお、このようなテヌブルには䞀時的なデヌタが含たれたすが、これは倱うものではありたせん。 最初の損倱の埌、デヌタはミッションクリティカルであり、倱うこずはできないこずが刀明したした。 そしお、デヌタベヌスずアプリケヌションのアヌキテクチャはすでにこれらのテヌブルにしっかりず「怍え付けられ」おおり、その結果、誰もがそれらのテヌブルで祈るようになり、デヌタベヌスを定期的に再起動するず、テヌブルをディスク氞続圢匏に倉換し、メモリず同様のシャヌマニズムに倉換するずいう特定の儀匏に倉わりたす。



䞀般に、PostgreSQL自䜓はメモリ管理の点で単玔に適切であり、デヌタベヌスに十分な量が割り圓おられおいる堎合、そのようなテヌブルをRAMに保持し、アプリケヌションからの芁求に応じお行を提䟛するこずは玠晎らしいこずです。 それでも、テヌブルのワヌクロヌドが非垞に倧きい堎合、十分なメモリがない堎合、たたは氞続テヌブルのアプリケヌションを凊理する時間がたったくない堎合は、キヌワヌドUNLOGGEDCREATE UNLOGGED TABLE ...を䜿甚しおPostgreSQLで同様のテヌブルを䜜成するこずで、メモリテヌブルの動䜜を゚ミュレヌトできたす。 ドキュメントの匕甚



指定した堎合、テヌブルはログなしのテヌブルずしお䜜成されたす。 ログされおいないテヌブルに曞き蟌たれたデヌタは、先行曞き蟌みログ第29章を参照に曞き蟌たれないため、通垞のテヌブルよりも倧幅に高速になりたす。 ただし、クラッシュセヌフではありたせん。ログに蚘録されおいないテヌブルは、クラッシュたたはクリヌンシャットダりンの埌に自動的に切り捚おられたす。 ログに蚘録されおいないテヌブルの内容もスタンバむサヌバヌに耇補されたせん。 ログに蚘録されおいないテヌブルに䜜成されたむンデックスも自動的にログに蚘録されたせん。




マッチの節玄



倚くのMySQLアヌキテクトは、䞻キヌの正しい配眮や関係関係の正確性の維持など、非垞に重芁なこずを忘れがちですが、1぀たたは別の敎数に远加された数字のビット深床ず笊号を非垞に正確に瀺すこずが圌らの矩務であるず考えおいたす。 MySQLは非垞に倚様なデヌタ型int、smallint、tinyintなどを提䟛し、それぞれに察しお最倧文字数ず負の倀の有無を指定できたす。 たずえば、TINYINTは-128〜127の倀を保持し、UNSIGNED TINYINTは0〜255の倀を保持したす。



前述の建築家が決しお思い぀かないのは未来です。 遅かれ早かれ、指定されたフレヌムワヌクに収たらない倀がそのようなフィヌルドに到着し、MySQLは最も近い有効な倀に切り捚おられ、デフォルトでは厳密モヌドが無効になりたす。 そのような愚かさのために、客芳的に重芁で実際の数のパフォヌマンスむンゞケヌタヌが、蚱容される最倧倀の高い倀たで「カットオフ」され、システム党䜓の効率が䜎䞋するデヌタベヌスを繰り返し芳察したした。



知識のある人は、同様に、お金などの重芁な䜕かを䌝統的に保存する10進数/数倀タむプでも同様の状況が発生するこずをすでに掚枬しおいたす。 そのような堎合、実質利益の損倱に぀いおはすでに話をするこずができたす。 PostgreSQLは、足でたたは頭でさえ自分自身を撃぀機䌚のそのような動物園から免れ、指定された「定数」を超えるこずを垞に誓いたす。



IGNORE + ON DUPLICATE KEYを挿入...曎新



MySQL開発者に最も愛されおいる構造のいく぀かは、PostgreSQLに盎接類䌌しおいたせん。



INSERT IGNOREの継続的な䜿甚は、デヌタベヌススキヌマの蚭蚈䞊の問題を匷く瀺唆しおいたす。 ただし、INSERTを実行し、UNIQUE EXCEPTIONが発生した堎合にそれをむンタヌセプトし、サむレントに「消す」ストアドプロシヌゞャを蚘述するこずで、この動䜜を゚ミュレヌトできたす。



ON DUPLICATE KEY ... UPDATE、たたはいわゆるUPSERTUPdate + inSERTは、PostgreSQLコミュニティで必芁な「機胜」ずしお認識されおいたした。 そのリリヌスは、DBMS 9.5バヌゞョンに割り圓おられおいたす。 それたでは、次の構成でこれを゚ミュレヌトできたす。



--   ,      UPDATE existing_table ex SET field1 = ex.field1 + up.field1, field2 = up.field2, 
 FROM updates up WHERE ex.pkey_field1 = up.pkey_field1 AND ex.pkey_field2 = up.pkey_field2 
; --   INSERT INTO existing_table (columns, 
) SELECT new.field1, new.field2, 
 FROM new_data new WHERE NOT EXISTS ( SELECT * FROM existing_table ex WHERE ex.pkey1 = new.pkey1 and ex.pkey2 = new.pkey2 and 
; );
      
      







MySQLで時間を操䜜する



この目的のためにMySQLで利甚可胜なデヌタのタむプの時間倀を䞞める問題に぀いおはすでに述べたした。 それずは別に、このような情報を保存するためのさたざたな可胜なオプションを怜蚎したす。 これ自䜓はカテゎリヌ的な問題ではありたせん。すべおの問題は、開発者が型の違いを知らないこずに起因し、その結果、目に芋えるロゞックなしに䞀床​​に軜薄に䜿甚されるこずに起因したす。 DATETIME、TIMESTAMP、およびBIGINTUnixタむムスタンプ倀甚を䜿甚しお時刻を栌玍する状況は非垞に芏則的であり、ほが1秒おきに芳察されたす。



DATETIMEは、タむムゟヌンオフセットを栌玍する点でTIMESTAMPず異なりたす。 これに基づいお、PostgreSQLの適切なデヌタ型タむムゟヌンのある/ないタむムスタンプを蚈画し、オンザフラむでむンポヌトするずきにタむムゟヌンの修正をむンポヌト/枛算する準備をしたすデヌタベヌスが特定の「タむムゟヌン」にハヌドコヌディングされおいる堎合、およびデヌタタむプこれは無差別に䜿甚されたす。



同様に重芁なのは、bigintなどのフィヌルドにUNIXタむムスタンプを保存する問題です。 MySQLには、タむムゟヌンオフセットに察応する秒数をこの倀に远加するずいう䞍快な慣行がありたすが、これはむデオロギヌ的にはUTCのたたにする必芁がありたす。 この動䜜は暙準ではないため、バヌゞョン9.2以降、PostgreSQLは䞍快な回避策を䜿甚しおEXTRACT SQLコンストラクトEPOCH FROM TZVALUE :: TIMESTAMP WITH TIME ZONEの圢匏でタむムゟヌンの゚ポックを調敎する必芁がありたす。指定されたタむムスタンプからの゚ポック倀。タむムゟヌンストレヌゞを䜿甚する圢匏に明瀺的に倉換したす。



タむムゟヌンの操䜜は、゚ラヌの存圚が蚱される操䜜の1぀です。これは、タスクが本圓に重芁であるためです。 PostgreSQLでタむムゟヌンを操䜜するための正しいアプロヌチの説明は、 www.depesz.com / 2014/04/04 / how-to-deal-with-timestampsにある玠晎らしい蚘事に蚘茉されおいたす 。



ロック



倚くの堎合、プログラマはデヌタベヌスロックを手動で管理するこずを奜みたす。 共有ロックず排他ロックを明瀺的に蚭定するか、さらに悪いこずに、デフォルトのトランザクション分離レベルを倉曎したす。 厳密に蚀えば、これを行うこずは厳密に犁忌です。 それにもかかわらず、実際には、アヌキテクトが曎新されたテヌブルの「聎芚障害者」ロックによっお操䜜の敎合性を実装するこずを決定した状況がありたした。 同時に、ナヌザヌむンタヌフェむスからのOLTPロヌドが同じテヌブルに送られるこずを心配する人はほずんどいたせんでした。 倚くの堎合、このような衝動は、非トランザクションテヌブル゚ンゞンの存圚たたはデヌタベヌスを支配する蚭定に関する䞀般的な狂気のために、MySQLトランザクションが適甚できないずいう事実から生じたす。 たずえば、「タむムアりト」が制限たで緩められ、通垞のトランザクションが適甚されないずいう長いリク゚ストがありたす。



移行䞭のこの問題に察する最善の解決策は、PostgreSQLで正盎なトランザクションを䜿甚しおみるこずです。これは、同時実行性の高い状況に察凊する可胜性が高いです。 結局のずころ、ロックがロゞックの䞍可欠な郚分である堎合は、アドバむザリヌロックメカニズムを怜蚎しおください。 いわゆるアドバむザリロックは仮想的なものであり、物理デヌタのブロックには぀ながりたせん。 トランザクション内でそれらを適切に䜿甚するず、リスクが倧幅に䜎䞋し、DBMSのリ゜ヌスずパフォヌマンスがより節玄されたす。 しかし、もちろん、誰もあなたの頭で考えお、アプリケヌションコヌドでロックを適甚するすべおの「ケヌス」を泚意深く監芖する必芁性をキャンセルしたせん。



おわりに



MySQLデヌタベヌスサヌバヌで発生する可胜性のある驚くべきこずのほんの䞀郚のみを調べたした。 MySQLの耇雑なレプリケヌションず、PGを䜿甚しお耇補する方法に぀いお、非垞に長い間議論するこずができたす。たずえば、次のPG Day'15 RussiaでOleg Tsarevが行いたす。 最良の堎合、問題はホットスタンバむメカニズムを䜿甚しお解決されたす。 最悪の堎合、サポヌトず操䜜においおSlonyのような重芁なツヌルを習埗する必芁がありたす



これらの䟋が、移行のタスクが既存のツヌルを䜿甚した耇雑で実質的に解決䞍可胜なプロセスである理由を説明しおくれるこずを願っおいたす。 思慮深い、手動のアプロヌチのみで動䜜するこずが保蚌され、叀い軍事の知恵は「あなたのデヌタを知っおいたす」。



All Articles