PostgreSQLエバンジェリストメモ:有能なMySQLの批判

画像



こんにちは、Habr! この投稿は、MySQLについてのいくつかの一般的な神話や伝説を払拭する試みです。 筆者は、MySQLにはない varanio PostgreSQLの機能の公開であり 、ここからはその逆であるため、ハブと間違えませんでした。 MySQLの批判に関する出版物自体は、不完全ではありますが非常に正しいものですが、それに対するコメントは悲しい考えを示唆しています。



一般的に言えば、PostgreSQLに実装されていないか、さらに悪い実装されているMySQL機能に関する投稿を書くつもりでした。 しかし、1つの出版物の多くのトピックに干渉しないように、私が非常によく知っているもの(MySQL)と私が非常によく知らないもの(PostgreSQL)に比べてかなり難しい仕事を考慮するために、この出版物を後で延期することにしました。始めるには、すぐにvaranioの出版物からのコメントの多くに答えてください



なぜこれが必要なのですか? まあ、最初に、 再びインターネットで、誰かが間違っています。 問題自体はそれほど大きくないが、残念なことに、これらのクールなストーリーの多くはインターネット上だけでなく、 エリートスピーカーによるエリート会議を含むさまざまなロシアの会議でも聞く必要があります。 特にPostgres Professional会社の代表者からMySQLに関するまったく正しくない声明を聞くのは非常に同情的で、彼女にあらゆる種類の成功と繁栄を願っています。 したがって、 文化交流の一環として、PostgreSQLとMySQLの長所と短所に関する議論の技術レベルを高めるために、まずは典型的な誤解を分析するだけでなく、正しい言葉遣いを提案し、MySQLの本当に深刻な(私の意見では)問題を概説したい現在の瞬間。



だから、若い世話人の学校。 レッスン1:「MySQLを有能に批判します。」 ティンク!



MySQL 批判しない方法



最も単純な神話、技術に近いものから始めましょう。



「MySQLはレガシー」



MySQLがインフラストラクチャとビジネスで重要な役割を果たしている有名企業のリストを、Github、Wikipedia、Google、Facebook、Twitter、LinkedIn、Alibaba、Taobao、Booking.com、AirBnB、Dropbox、Pinterest、GroupOn 、Yelp。



PostgreSQLには大規模で有名なプロジェクトがあることを知っています。 しかし、最初に、これらのプロジェクトと規模を比較できる人はほとんどいません。 そして第二に、このリストは、誰かが「MySQLは必要ありません」というスタイルで思いやりのある何かを出すときに現実との接触を失わないように、覚えておくと便利です。



「MySQLにはコミュニティがありません!」



コミュニティの範囲と活動を評価するための基準は長い間議論されていますが、 http://db-engines.com/en/rankingの基準は私にとってかなり合理的です。



一方、ロシアでは、PostgreSQLの人気とコミュニティの活動は、実際には「世界平均」の傾向よりもわずかに高くなっています。 何がこれを引き起こしたのかはよくわかりませんが、何も問題はありません。



「MySQLにはコミュニティがありますが、断片化しています!」



一般的に、私はここで何を意味するのか理解できませんでした。 MariaDBを使用するには、Oracle MySQLユーザーを完全に再トレーニングする必要があるようです。 または、MariaDBで作業しているDBAは、Percona Serverについてまったく知りません。 実際には、スキル、書籍、記事、ユーティリティ、どこかで入手したヒントなどの99%は、MySQLのどのバージョンでも安全に使用できます。



「MySQLには多くの分岐点があり、混乱している」



数年前にロシアの会議でこの奇妙な声明を初めて聞いた。 それ以来、私は自分が話していることを明らかにあまり知らない人々からこれをよく耳にします。 上記のポストvaranioを含む。 次の2つの簡単な質問に対して明確な答えを得ることができませんでした。







今回も明確な回答を得ることができませんでしたが、私はもはや望みませんでした。 無料のオープンソースソフトウェアの開発では、「フォーク」が常に発生します。 この場合、通常は無料でオープンであると考えられます。 さらに、MySQLには、他の多くの有名なプロジェクトよりもさらに少ないフォークとブランチがあります。 その点で、 PostgreSQL自体よりも少ないです。



ところで、この議論はMicrosoftのFUDと驚くほど似ています。 これが、Microsoftが今世紀初頭にLinuxの優位性を宣伝した方法です。







「MySQLはOracleに属します(PostgreSQLは誰にも属しません)」



もちろんこれは事実ですが、これから重要な結論を導き出すことができますが、私はあまり理解しておらず、批評家の思考の飛行は通常そこで止まります。



理論的には、Oracleにはプロジェクトを最小化する、ソースを閉じる、支払いを行う権利があります。 それがいかに現実的か-誰もが自分で決めることができます。 私にとって、これは絶対に非現実的です-これはOracleによるSun Microsystemsの購入時に恐れられる可能性がありますが、5年が経過しました(カール!)この間、MySQLは購入前よりも速く開発されています。 さらに、Oracleには愚か者はいません。MySQLを閉じると、Oracle自体が最も打撃を受けることをよく知っています。



「主観的に、PostgreSQLにはバグが少ない」



そうかもしれませんが、PostgreSQLにトラッカーバグがない場合、 客観的にどのように比較しますか?



これについては、技術的な神話ではなく、実質的な神話を終わらせます。



「PostgreSQLはMySQLよりも何倍も高速です」



何年もの間、MySQLコードを最適化してきました。その結果、負荷テストを頻繁に行いますが、ほとんどの場合、異なるバージョンとMySQLのバージョン間で行います。 そのようなステートメントについて私が言えることは次のとおりです:PostgreSQLがMySQLよりも何倍も高速に動作するロード/クエリ/構成があることは絶対に確信しています。反対のことを確信しているように-ロード/クエリ/構成がありますMySQLはPostgreSQLよりも数倍高速です。 MySQLの場合、もう1つの重要な基準があります。使用済みエンジン(ストレージエンジン)で、状況を時々だけでなく、桁違いに変更することもできます。



誰かが(MySQLやPostgreSQLに関係なく)パフォーマンスについて不平を言うたびに、スキーマ/クエリ/説明/構成を表示するように求められます。 これは偶然ではありません。パフォーマンスに関するすべての話は、この文脈でのみ行うことができます。 一般的な声明は引用されていません。



「PostgreSQLのレプリケーションはスマートです。 しかし、MySQLには「



MySQLは(ステートメントベースまたは行ベースの形式に関係なく)論理レプリケーションを実装します。 PostgreSQLでは、レプリケーションは物理的です(「バイナリ」ではなく物理的です)。



それぞれのアプローチには長所と短所があります。 これを理解するために、DBMSの専門家である必要はありません。 MySQLユーザーは、論理複製の悪影響を回避または平滑化する優れた経験を積んでいますが、どちらかが必要なため、いつかは物理的に現れる可能性があります。 PostgreSQLでも同様のプロセスが進行していると思われますが、反対の方向です。



このトピックは非常に広範囲であり、非常に多くの質問を提起するので、別の投稿について考えています。



「MySQLはデータを大まかに操作しています。」



オプション:「MySQLは静かにゼロで除算します!」



技術的には正しいが、このステートメントの退屈なバージョンは次のとおりです。「MySQLバージョン<5.7では、正しいSQLモードを有効にすることを忘れないでください



5.7では、重大度の設定はデフォルトでかなり合理的です。 これがあまりにも長い間行われなかった理由は平凡です。人気のあるプロジェクトに関しては、MySQLの主な競合相手は独自の古いバージョンです。 古い曲がったアプリケーションとの後方互換性を引き出す必要があります。 5.7で、彼らはこれを終了することにしました。これは良いことです。



「MySQLにはMyISAMのような非トランザクションエンジンがあります」



はい、しかし、批判が何であるかはあまり明確ではありません。 2015年にMyISAMについて話すことは、レガシーアプリケーションをサポートするという点でのみ可能です。 正直なところ、5年前にライブのMyISAMユーザーと最後に会ったときです。



非トランザクションエンジンがありますが、そこからトランザクションは必要ありません。 たとえば、 CSV 。 PostgreSQLユーザーが理解しやすくするために、CSVエンジンはfile_fdwのようなものです 。 他のアプリケーションとデータを交換する可能性が高く、実際にデータを保存する可能性は高くありません。



「MySQLでは、トランザクションは何らかの形で横にねじ込まれています



これにより、誰もが自分自身の何かを理解します。 誰かがそう考えているのは、トランザクションでDDLをラップできないからです。 もちろんこれは事実ですが、問題は「サイドからのトランザクション」からではなく、DDLカーブから発生します(これについては、「MySQLを批判する方法」セクションで詳しく説明します)。



退屈で技術的に正しいオプション:「MySQLには非トランザクションDDLがあります。」



誰かが、トランザクション内のエラーが自動的にロールバックしないと言います。 はい、さまざまなエラー(ロック待機タイムアウトなど)があり、それらのエラーに対してアプリケーションは最後のステートメントを繰り返すことができ、トランザクション全体をロールバックすることはできません。 私の知る限り、OracleとSQL Serverはデフォルトで同じように動作します。これは標準に違反するものではありません。 PostgreSQLでは、エラーが発生した場合に最後のステートメントを繰り返すことができるように、各ステートメントをSAVEPOINTのトランザクション内にラップする必要があります。 たとえば、psqlでON_ERROR_ROLLBACKが出現しました。 つまり いつものように、アプローチは長所と短所で異なります。



「MySQLには非常に高価なDDLがあります」



これは、制約を削除するときなど、特定の操作のためにテーブルを再作成することを指します。 すでに5.6では、ほとんどすべての操作に対してテーブル再作成せずにALTERを実行できます。 特に、制約は再作成せずに削除できます。 5.7では、インプレース操作のリストはさらに広くなりました。



PostgreSQLがこれをどのように処理するかわかりません(クイック検索で特定の問題があることがわかります)。 しかし、MySQLにはユーティリティpt-online-schema-changeがあります。これにより、MySQLのALTER TABLEの多くの制限を回避でき、多くの場合、知られていないか忘れられていません。



「MySQLには何らかの間違った MVCCがあります」



InnoDBのMVCCエンジンは適切に実装されています。 ユーザーの観点からは、OracleのMVCC実装とほぼ同じであり、PostgreSQLの実装と非常によく似ています。 しかし、多くの人々の行動の違いは、それが同様の神話を引き起こすことに驚いています。 実際、この規格では、さまざまな分離レベルで多くの微妙な瞬間が非常に不明確に定義されています。 その結果、各DBMSはこれらの「ギャップ」を独自の方法で解釈します。 Oracle、PostgreSQL、およびMySQL / InnoDBでのMVCCの優れた比較については、 こちらをご覧ください 。 しかし、そこであっても、すべてのニュアンスが反映されるわけではありません。



過去10年にわたって、InnoDBでMVCCを最適化および拡張するために多大な労力が費やされてきました。 これにも付けました。



2017年4月2日更新: PostgreSQLおよびMySQLを含むさまざまなDBMSでのMVCCの実装の違い理解するためのより正式な試み



「プラグインエンジンのため、MySQLは戦時中にディスク2、3、4、5回にデータを書き込みます」



素朴な声明。 ロジックは単純です:







ここで、「書き込み増幅」機能について説明する必要があります。 ロシア語で良い用語を見つけることはできませんでしたが、本質的には、クライアントによって送信されたデータの合計量に対するディスクに書き込まれたデータの合計量の比率です。 それが何で構成されるかを見てみましょう。



まず、データファイルへの書き込みは、更新されたページをディスクにリセットするときにのみ発生します。 ディスクにフラッシュする前にメモリ内でページを更新できる時間(およびそれに応じて、書き込み増幅がどれだけ変化するか)は、多数のパラメーターに依存します:共有バッファー(InnoDBのバッファープール)のサイズ、トランザクションログのサイズ、ページフラッシュを制御するアルゴリズムサーバー設定、そしてもちろん負荷の種類。 これはすべてMySQLとPostgreSQLの両方に適用されます。



次に、トランザクションログには、テーブル内のレコードの更新だけでなく、データファイルのすべての物理的な変更も含まれます。 例としてInnoDBを使用すると、これはインデックスツリー(入力時のページ分割、削除時のマージ、ツリーの再構築など)、古いバージョンのレコードの削除(パージ操作)、変更バッファーおよびその他の内部アカウンティングの管理です。 これは、MySQLとPostgreSQLの両方にも適用されます。



第三に、バイナリログにはデータの論理的な変更のみが含まれます。データファイルの形式とその内部アカウンティングについては何も「知りません」。 バイナリログの書き込み増幅は、多くのパラメーター(ステートメント/行ベース、binlog_row_imageおよびその他の設定)に依存します。 さらに、バイナリログを無効にすることができます-それは頻繁に必要ですが、常にではありません。



最後に、doublewriteバッファーは、ページがディスクにフラッシュされるときにのみ使用され、すべてのINSERT / DELETE / UPDATEではありません。 完全に類似したメカニズムは、プロファイルのみで、PostgreSQLでは「全ページ書き込み」と呼ばれます。 そして、あちこちで特定の条件下でオフにすることができます。



また、データ形式の冗長性(つまり、サービス情報のオーバーヘッド)、ページサイズ(データベースの作成時にInnoDBで指定できます)、圧縮などを考慮する必要があります。



これらすべてから、書き込み増幅特性を計算することは不可能であることは明らかです。パラメータが多すぎます。 特定の負荷、特定の構成、および(MySQLの場合)特定のエンジンについて測定できます。 たとえば、TokuDBやMyRocksなどの記録最適化エンジンの場合、この特性はInnoDB用に作成されているため、InnoDBよりもはるかに低くなります。



言えることは、バイナリログ(有効な場合)が追加の書き込みオーバーヘッドを引き起こすということです。 コストの大きさ、および書き込みの合計増幅がPostgreSQLの同じ特性よりも大きくなるかどうかは、特定の負荷と構成をおおよそ測定しなくても言えません。



そのような退屈な真実。



「MySQLのログが多すぎます」



私はすべての種類の雑誌を描くつもりはありません;それらの目的はだいたい誰にでも明らかです。 質問の多くはバイナリログによって発生します。 バイナリログは、プラグインエンジンを使用するための「料金」です。 「接続」は、プラグインとして動的に接続できるという意味ではなく(以前はそのような機会はありませんでした)、それらのいくつかがまったく存在できるという意味で、サーバーはAPIを介して異なるエンジンで動作します。



ディスク上のデータの物理表現は、使用するエンジンによって異なる場合があり、レプリケーションにはすべての変更の単一のシリアル化された表現が必要であるため、そのような表現は物理データから抽象化された論理形式で記述されます。 すでに書いたように、データを更新するとき、論理ログは必ずしも物理ログのエントリを複製しません。



論理ログと論理レプリケーションを使用すると、あらゆる種類の興味深いことができます。 特に、Galeraテクノロジーで積極的に使用されています。 次の投稿で、このすべての経済の概要を説明します。



「MySQLには悪いコンソールクライアントがあります」



私が理解しているように、これは状況依存のオートコンプリートが存在しないことを意味します。 私は同意します、それは便利です。 しかし、これを感じるためには、コンソールクライアントで多くの時間を費やす必要があります。 開発者として、エディターでより多くの時間を費やしています。 DBAのほとんどの作業は、コンソールクライアントで手動で行うのではなく、スクリプトによっても実行されるように思えます。



しかし、本当にそれを必要とする人のために、 mycliプロジェクトは最近、スマートなオートコンプリート、さらには構文の強調表示で登場しました。 そして、美しいGUIが好きな人には、MySQL Workbenchがあります。 どちらか一方を使用したことはありません。



2017年5月10 日更新: Oracleの新しいコマンドラインクライアントであるMySQL Shellのベータ版では、SQLの自動補完がサポートされています。



いずれにせよ、「MySQLコンソールクライアントにはコンテキストに応じたオートコンプリートはありません」と言う方が正しいでしょう。なぜなら、すべての批判がこれに来ているようだからです。



どうすれば MySQL 批判できますが、もはや関連性がなくなりますか?





それとは別に、一般的には正しいが、MySQL 5.7の差し迫ったリリースに照らして関連性を失うステートメントを強調したいと思います。



「MySQLにはJSONサポートがありません」



以前は、 svetasmirnovaの JSON UDFで限定的なサポートが行われていました。 5.7にはネイティブサポートがあります。 PostgreSQLとどれだけ匹敵するかは言えませんが、いずれにしても、この形式の記述はすでに古くなっています。



「MySQLには機能インデックスがありません」



5.7では、機能インデックスはインデックス可能な仮想/生成列として実装されます。 MariaDBには長い間存在していましたが、マテリアライズされた仮想列に対してのみインデックス付けが可能です。



MySQL 批判するには?





おそらく最も興味深い部分に移ります。 実際に深刻な問題がありますが、ホリバーでそれらについて非常にめったに言われません。 実際、会議でのブログやレポートから判断すると、MySQLユーザーは、たとえばウィンドウ機能がないことではなく、水平スケーリング、シャーディング、クラスタリング、高可用性、クラウドプラットフォーム、および関連する自動化、監視、情報保護の問題に関心がありますなど。 その結果、これらの分野では開発者の努力が集中しています。



しかし、ここではPostgreSQLコミュニティからの批判について話しているので、原則としてこれらのすべての問題に触れているわけではないので、ここでは、以前に聞いたり読んだりしたものからの公正で、私の意見では、技術的に正しく定式化された重要なコメントをリストします



トランザクションデータディクショナリの欠如



MySQLでは、「データディクショナリ」は非トランザクションファイル(.frm、.parなど)のコレクションであり、これは最も古くからの難しい遺産であり、膨大な数の問題を引き起こします。



これは、データディクショナリが前提条件であるトランザクションDDLが存在しないだけではありません。 これらは、INFORMATION_SCHEMAへの高価なクエリの問題、メタデータ形式の拡張性の問題、非トランザクションディクショナリとのトランザクションデータの一貫性を確保するために本質的にサーバーをブロックせざるを得ない物理バックアップの問題などです。



このすべての作業が開始されましたが、5.7で結果が表示されることはありません。



Oracleの場合、InnoDBのみが存在します



残念ながら、オラクルは明白な理由でサードパーティのエンジンの運命を特に心配していません。 「プラグイン」エンジンの概念が近い将来廃止されるとは思いませんが、明らかに他のエンジンのサポートを引き受けません。



その結果、多くの機能はInnoDBにのみ実装されています。 例:外部キー、全文検索、空間インデックス、仮想列。 TokuDBやMyRocksでこれらすべての機能がすぐに登場することはまずありません。 また、実装された場合、InnoDBの機能と互換性がなくなります。



不完全なクエリオプティマイザー



オプティマイザーは常にMySQLの弱点の1つです。 詳細な議論を始めると、ほとんどの批評家が5〜10年前に修正された問題について話し始めると思いますが。 新しいバージョンにはそれぞれ便利な改善点がありますが、それでも多くの人が望むよりも進行が遅いです。 これには歴史的な理由がありますが、ここでのポイントは、非常に不完全なオプティマイザアーキテクチャのようにプラグインエンジンの概念ではありません。 重大な修正とリファクタリングが必要であり、Oracleはこの方向で作業を進めていますが、そのようなことを迅速に行うことはできません。



高度なSQLの弱いサポート



この問題は、以前の問題に部分的に関連しています。 しかし、はい、ウィンドウ関数、CTEなどはありません。 これがMySQLユーザーにとってどれほど重要かは未解決の問題です。 すでに書いたように、会議でのブログやレポートでは、SQL機能が本当に不足していると言うことはできません。 MySQLリリースの変更から判断すると、Oracleにとってもこれは最高の優先順位からはほど遠いものです。





2017年5月10日更新: CTEおよびウィンドウ関数のサポートがMySQL 8.0で登場しました。 興味深いことに、有名なPostgreSQLエバンジェリストMarcus Vinandaのテスト結果によると MySQLは現在、PostgreSQLを含むすべての一般的なDBMSの中で最も包括的なCTEサポートを持っています。



弱いGISサポート



これも真の批判ですが、オラクルでの私の意見では、これは真剣に受け止められています。 5.7では、GISをゼロから書き直し、空間インデックスをInnoDBに追加し、自己記述コードの代わりにBoost.Geometryを使用し、コンプライアンスに関する作業を開始しました。 将来のバージョンには多くの興味深いことがあると思います。



2017年5月10日更新: MySQL 8.0でGISサポートが大幅に拡張されました。 重要な点-非デカルトSRSのサポートおよび空間データを処理するための拡張機能セット。 詳細については、 このプレゼンテーションをご覧ください 。 これをPostGISと比較することも興味深いでしょう。 このトピックに精通している人々との私のコミュニケーションから判断すると、ある時点で、PostGISはすでにMySQL 8.0の組み込みGISサポートよりも機能が劣っています。



おわりに



確かに各セクションで何かを見落としていましたが、コメントでそれを補うと確信しています。 単一の出版物ですべてをカバーすることは不可能ですが、誰かがこの出版物をHabréでのMySQLの批判や会議で思慮深く懐疑的にするなら、私はボタンを押しました。 PostgreSQLに実装されていない、またはさらに悪いMySQLの論理/物理レプリケーションと機能について別々に書くには、興味があります。



All Articles