質問

hbm2ddl.auto = update で構成されたHibernateアプリケーションを実行して、本番環境でデータベーススキーマを更新しても大丈夫ですか?

役に立ちましたか?

解決

いいえ、安全ではありません。

Hibernateチームの最善の努力にもかかわらず、本番環境での自動更新に頼ることはできません。独自のパッチを作成し、DBAでレビューし、テストしてから、手動で適用します。

理論的には、 hbm2ddl更新が開発で機能していれば、本番でも機能するはずです。しかし、実際には、常にそうであるとは限りません。

正常に機能したとしても、最適ではない可能性があります。 DBAには多くの理由があります。

他のヒント

ミッションクリティカルではなく、スタッフに高額なDBAがいないアプリケーションを使用して、本番環境でそれを行います。人的エラーが発生するのは、手動プロセスが1つ少ないことです。アプリケーションは、違いを検出して正しいことを実行でき、さらに、さまざまな開発環境とテスト環境でテストしたと考えられます。

1つの注意点-クラスター環境では、複数のアプリが同時に起動し、スキーマを変更しようとする可能性があるため、回避する必要がある場合があります。または、スキーマの更新を1つのインスタンスのみに許可するメカニズムを追加します。

Hibernateの作成者は、本" Java Persistenceの本番環境でそうすることをお勧めしません。 Hibernateで"

  

警告:HibernateユーザーがSchemaUpdateを使用して本番データベースのスキーマを自動的に更新しようとしているのを見てきました。これはすぐに災害で終わる可能性があり、DBAによって許可されません。

更新の変更ログを保持するためのLiquiBase XMLをチェックしてください。私は今年まで使用していませんでしたが、DBの改訂管理/移行/変更管理を非常に簡単に習得し、非常に簡単にすることがわかりました。私はGroovy / Grailsプロジェクトに取り組んでおり、GrailsはそのすべてのORM(「GORM」と呼ばれる)にHibernateを使用しています。 Liquibaseを使用して、すべてのSQLスキーマの変更を管理します。これは、アプリが新しい機能で進化するにつれて頻繁に行われます。

基本的に、アプリケーションの進化に合わせて追加し続ける変更セットのXMLファイルを保持します。このファイルは、プロジェクトの他の部分とともにgit(または使用しているもの)に保持されます。アプリがデプロイされると、Liquibaseは接続しているDBのchangelogテーブルをチェックするため、すでに適用されているものを把握し、ファイルからまだ適用されていない変更セットをインテリジェントに適用します。実際には非常にうまく機能し、すべてのスキーマの変更に使用すると、チェックアウトしてデプロイするコードが常に完全に互換性のあるデータベーススキーマに接続できることを100%確信できます。

素晴らしいことは、ラップトップで完全に空白のスレートmysqlデータベースを取得し、アプリを起動すると、すぐにスキーマが設定されることです。また、最初にlocal-devまたはステージングdbにスキーマの変更を適用することにより、スキーマの変更を簡単にテストできます。

これを開始する最も簡単な方法は、おそらく既存のDBを取得してから、Liquibaseを使用して初期のbaseline.xmlファイルを生成することです。その後、将来追加するだけでliquibaseがスキーマの変更の管理を引き継ぐことができます。

http://www.liquibase.org/

Hibernateは、自動更新を使用しないことに関する免責事項をprodに入れて、自分が何をしているのかわからない人が使用すべきでない状況で使用する場合に自分自身をカバーする必要があります。

使用すべきでない状況が大丈夫な状況を大きく上回る。

私は長年にわたってさまざまなプロジェクトで使用してきましたが、一度も問題が発生したことはありません。それは不完全な答えではなく、カウボーイコーディングでもありません。これは歴史的な事実です。

「本番では絶対にやらない」と言う人生産展開の特定のセット、つまり、彼が精通しているもの(彼の会社、彼の業界など)を考えています。

「プロダクションデプロイメント」の世界広大で多様です。

経験豊富なHibernate開発者は、指定されたマッピング構成からDDLがどのような結果になるかを正確に知っています。期待するものがDDL(dev、qa、ステージングなど)で終わることをテストおよび検証する限り、問題ありません。

多くの機能を追加する場合、自動スキーマ更新はリアルタイムの節約になります。

自動更新で処理されないもののリストは無限ですが、いくつかの例はデータの移行、null不可の列の追加、列名の変更などです

クラスター環境でも注意する必要があります。

しかし、このすべてを知っていれば、この質問をすることはないでしょう。うーん。 。 。この質問をしている場合、prodでの使用を検討する前に、Hibernateと自動スキーマ更新の多くの経験を得るまで待つ必要があります。

いいえ、投票します。 Hibernateは、列のデータ型がいつ変更されたかを理解していないようです。例(MySQLを使用):

String with @Column(length=50)  ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)

@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed

おそらくString列の長さを255を超えて押し上げて、テキスト、中間テキストなどに変換するのを見るなど、他の例もおそらくあります。

確かに、「データ型を変換する」方法は本当にないと思います。新しい列を作成せずに、データをコピーして古い列を吹き飛ばします。しかし、データベースに現在のHibernateマッピングが反映されていない列があると、非常に危険な状態になります...

フライウェイは、この問題に対処するための優れたオプションです。

http://flywaydb.org

この記事で説明したように、本番環境では hbm2ddl.auto を使用します。

データベーススキーマを管理する唯一の方法は、インクリメンタル移行スクリプトを使用することです。

  • スクリプトは、コードベースに沿ってVCSに常駐します。ブランチをチェックアウトするとき、スキーマ全体を最初から再作成します。
  • 本番環境に適用する前に、増分スクリプトをQAサーバーでテストできます
  • スクリプトは Flyway で実行できるため、手動で介入する必要はありません。したがって、人間の可能性を減らします。手動でのスクリプトの実行に関連するエラー。

Hibernateユーザーガイド実稼働環境では hbm2ddl ツールの使用を避けることをお勧めします。

ここに画像の説明を入力

保存しておくべきデータが失われる可能性があるため、リスクはありません。 hbm2ddl.auto = updateは、開発データベースを最新の状態に保つための純粋に簡単な方法です。

私たちは現在数か月間本番環境で実行されているプロジェクトでそれを行いますが、これまで問題はありませんでした。このレシピに必要な2つの成分に留意してください:

  1. 後方互換性のアプローチ、つまり、オブジェクトと属性を削除/変更するのではなく、非推奨にすることで、オブジェクトモデルを設計します。つまり、オブジェクトまたは属性の名前を変更する必要がある場合は、古いものをそのままにして、新しいものを追加して、何らかの移行スクリプトを作成します。オブジェクト間の関連付けを変更する必要がある場合、すでに実稼働している場合、これは設計がそもそも間違っていたことを意味するため、古いデータに影響を与えずに新しい関係を表現する新しい方法を考えてみてください。

  2. 展開前にデータベースを常にバックアップします。

この投稿を読んだ後の私の感覚では、この議論に参加している人々の90%が、本番環境でこのような自動化を使用するという考えだけでぞっとしています。 DBAでボールを投げる 人もいます。ただし、すべてのプロダクション環境がDBAを提供するわけではなく、開発チームの1人が余裕がない(少なくとも中規模のプロジェクトの場合)ことを考慮してください。だから、みんながすべてをしなければならないチームについて話しているなら、ボールは彼らの上にあります。

この場合、なぜ両方の長所を最大限に活用しようとしないのですか?このようなツールは支援の手を差し伸べるために用意されており、慎重な設計と計画があれば、多くの状況で役立ちます。そして、私を信じて、管理者は最初は納得するのが難しいかもしれませんが、ボールが手にないことを知っているなら、彼らはそれを愛するでしょう。

個人的には、あらゆる種類のスキーマを拡張するために手作業でスクリプトを書くことは決してありませんが、それは私の意見です。また、最近NoSQLスキーマレスデータベースの採用を開始した後、これらのスキーマベースの操作はすべて過去のものであることがすぐにわかるので、視点を変えて先を見越した方がよいでしょう。

  • 私の場合(Hibernate 3.5.2、Postgresql、Ubuntu)、 hibernate.hbm2ddl.auto = update を設定すると、新しいテーブルが作成され、既存のテーブルに新しい列が作成されます。

  • テーブルの削除も、列の削除も、列の変更も行いませんでした。安全なオプションと呼ぶこともできますが、 hibernate.hbm2ddl.auto = create_tables add_columns のようなものがより明確になります。

安全ではなく、推奨されませんが、可能です。

実稼働環境で自動更新オプションを使用したアプリケーションの経験があります。

さて、このソリューションで見つかった主な問題とリスクは次のとおりです。

  • 間違ったデータベースにデプロイする。間違ったデータベースの古いバージョンのアプリケーション(EAR / WAR / etc)でアプリケーションサーバーを実行するというミスを犯した場合...多くの新しい列、テーブル、外部キー、エラーが発生します。同じ問題は、データソースファイルの単純なミスでも発生する可能性があります(ファイルをコピー/貼り付けし、データベースの変更を忘れた)。再開すると、状況はデータベースの災害になる可能性があります。
  • アプリケーションサーバーの起動に時間がかかりすぎる。これは、アプリケーションを起動するたびに、Hibernateが作成されたすべてのテーブル/列/などを検索しようとするために発生します。彼は、作成する必要のあるもの(テーブル、列など)を知る必要があります。この問題は、データベーステーブルが大きくなるにつれて悪化します。
  • ほとんど使用できないデータベースツール。新しいバージョンで実行するデータベーススクリプトを作成するには、アプリケーションサーバーの起動後に自動更新によって何が作成されるかを考える必要があります。たとえば、新しい列にデータを入力する必要がある場合は、アプリケーションサーバーを起動し、Hibernateが新しい列を作成するのを待ってからSQLスクリプトを実行する必要があります。ご覧のとおり、データベース移行ツール(Flyway、Liquibaseなど)は、自動更新を有効にして使用することはほとんど不可能です。
  • データベースの変更は集中化されません。 Hibernateがテーブルおよびその他すべてを作成する可能性があるため、アプリケーションの各バージョンでデータベースの変更を監視するのは困難です。ほとんどの変更は自動的に行われるためです。
  • データベース上のゴミを奨励します。自動更新が容易なため、チームが古い列や古いテーブルを削除し忘れる可能性があります。
  • 差し迫った災害。生産で発生する何らかの災害の差し迫ったリスク(他の回答で言及された一部の人々と同様)。実行中のアプリケーションが何年も更新可能であっても、安全だとは思いません。このオプションをオンにしても安全だとは思わなかった。

したがって、実稼働環境で自動更新を使用することはお勧めしません。

本番環境で自動更新を本当に使用する場合は、以下をお勧めします。

  • 分離されたネットワーク。テスト環境はホモログ環境にアクセスできません。これにより、テスト環境にあるはずのデプロイメントがホモロゲーションデータベースを変更するのを防ぐことができます。
  • スクリプトの順序を管理。デプロイ前に実行するスクリプト(構造テーブルの変更、テーブル/列の削除)とデプロイ後のスクリプト(新しい列/テーブルの情報を入力)を整理する必要があります。

そして、他の投稿とは異なり、自動更新が有効になったとは思わないDBA(他の投稿で述べたように)... DBAには、テーブルや列を作成/変更/削除するSQLステートメントを書くよりも重要なことがあります。これらの簡単な日常のタスクは、開発者が実行および自動化でき、HibernateとDBAが「非常によく支払われる」必要なく、DBAチームがレビューするためだけに渡されます。それらを書きます。

いいえ、絶対にやらないでください。 Hibernateはデータの移行を処理しません。はい、スキーマは正しく表示されますが、貴重な本番データがプロセスで失われないことは保証されません。

  • 通常、大規模な組織のエンタープライズアプリケーションは、低い権限で実行されます。

  • データベースのユーザー名には、 hbm2ddl.auto = update が必要とする列を追加するための DDL 特権がない場合があります。

ウラジミールに同意します。私の会社の管理者は、私がそのようなコースを提案したとしても、間違いなく感謝しません。

さらに、Hibernateを盲目的に信頼する代わりにSQLスクリプトを作成すると、使用されなくなったフィールドを削除できます。 Hibernateはそれを行いません。

また、本番スキーマと新しいスキーマを比較すると、データモデルで変更したものについてより良い洞察を得ることができます。もちろん、あなたはそれを作ったから知っていますが、今ではすべての変更を一度に見ることができます。あなたを行かせてくれるものでさえ、「一体何だ!」のように。

スキーマデルタを作成できるツールがありますので、大変な作業でもありません。そして、あなたは何が起こるかを正確に知っています。

アプリケーションのスキーマは時間とともに進化する可能性があります。異なるバージョンである可能性のある複数のインストールがある場合、アプリケーション、ある種のツールまたはスクリプトがスキーマとデータをあるバージョンから次のバージョンに段階的に移行できることを確認する方法が必要です。

Hibernateマッピング(またはアノテーション)の永続性をすべて保持することは、スキーマの進化を制御し続けるための非常に良い方法です。

スキーマの進化には、考慮すべきいくつかの側面があることを考慮する必要があります。

  1. データベーススキーマの進化 列とテーブルを追加する

  2. 古い列、テーブル、および 関係

  3. デフォルトで新しい列を埋める

Hibernateツールは、(私の経験のように)多くの異なる種類のデータベースに同じアプリケーションの異なるバージョンがある場合に特に重要です。

ポイント3は、Hibernateを使用している場合、新しいブール値のプロパティまたは数値のプロパティを導入する場合、Hibernateがそのような列でnull値を見つける場合、例外を発生させる場合に非常に敏感です。

だから私はやる:スキーマ更新のHibernateツールの容量を実際に使用しますが、それに加えて、デフォルトの入力、使用されなくなった列のドロップなどのために、データとスキーマメンテナンスコールバックを追加する必要があります。このようにして、データベースに依存しないスキーマ更新スクリプト(永続性およびスクリプトでの更新の重複コーディングの回避)が得られますが、操作のすべての側面もカバーされます。

たとえば、バージョンの更新が、varchar値のプロパティ(したがって列)を追加するだけで構成されている場合、デフォルトではnullになりますが、自動更新が行われます。複雑さがさらに必要な場合は、さらに作業が必要になります。

これは、更新時にアプリケーションがそのスキーマを更新できることを前提としています(実行可能)。これは、スキーマで更新するためのユーザー権限が必要であることも意味します。顧客のポリシーがこれを防いでいる場合(おそらくLizard Brainの場合)、データベース-特定のスクリプトを提供する必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top