Skip to content

Database update system#14139

Closed
Naios wants to merge 1 commit intoTrinityCore:6.xfrom
Naios:dbupdater
Closed

Database update system#14139
Naios wants to merge 1 commit intoTrinityCore:6.xfrom
Naios:dbupdater

Conversation

@Naios
Copy link
Copy Markdown
Contributor

@Naios Naios commented Feb 13, 2015

Idea:

This pullrequest implements a great idea of @DDuarte mentioned in this post.

The idea is very simple: let the world and authserver update its database tables itself so you don't need to care about updates anymore -> say bye to "Your database structure is not up to date...", you won't see this message anymore ,-)

The procedure is following:

  • At startup the update system creates a list of all sql updates in some directories (sql/old, sql/custom and sql/updates)...
  • ... and compares it with a list stored in the database. (every database has its own list of applied updates - logical)
  • If needed the updater updates the database with all missing and changed files and synchronizes the list stored in the database.
  • The system detects changes on files since last startup through sha1 hashes.

How it works

Update process

2016-02-23_03-35-11

The pullrequest adds the functionality to both servers to create, populate and update its databases automatically.

Configuration:

  • The update system uses in-compiled cmake variables to detect your source directory that contains updates and your mysql cli binary.
  • Thats why the update system works out of the box in most cases.

Create databases:

  • If the database doesn't exists it asks for permission to create it.

Populate databases:

  • If the database doesn't contain any table it auto populates it from base/fulldumps.
  • Auth, character and hotfix db works out of the box, world db requires the current tdb release in your worldserver directory.

Update databases

  • The system detects recently added updates and applies it to the database.
  • It also detects changes on that file through hashes and reapplies it if necessary.
  • Renames of files don't lead to an reapply if the content didn't change, that makes it possible to rename files (because of name conflicts or codestyle fix) without worrying about reapplies.
  • Location of updates: sql\updates & sql\custom, it searches directories listed in the updates_include table recursively for updates so subdirectories are possible.
  • Updates have 2 states: ARCHIVED and RELEASED: every update is released until it gets archived (applied in the full db). Archived updates are not checked for changes to increase startup speed but it also checks whether an update was applied or not so you don't miss any update through database releases.

ToDo:

  • delay creation of prepared statements to prevent errors due to too early creation.
  • find a solution for old updates
  • import full databases on empty db's (tc auto setup).
  • generated hashes are not the same as those from command tools (openssl md5) (but are equal to hashes generated by webtools where you copy the content of the file in).
  • fix gcc/ clang build log
  • fix query benchmarking (works, tested with SELECT SLEEP(5))
  • Huge world dumps are not correcly applied stackoverflow question, its possible to use mysql cli as alternative. Hint -> using mysql cli now with boost::process
  • catch duplicated filenames.
  • catch renames.
  • copy everything in bnetserver, and update character and hotfixes db too
  • find out which server is responsible for which database (world -> auth & others) or (auth -> auth, world -> others)
  • _MYSQL_EXECUTABLE is not working after 2. cmake rerun! -> Log
  • Consider if we want to use sha1 instead of md5 to reduce possible collisions. -> Using sha1 now since its better in security (less collisions) and equal in speed (sometimes faster).

Ready to test!

For testing purposes append this to your full database. Otherwise world population won't be supported!

Finished

Working location

@DDuarte
Copy link
Copy Markdown
Contributor

DDuarte commented Feb 13, 2015

See https://github.com/jackpoz/TC-SQL-AutoUpdater by @jackpoz, it detects file changes using libgit

@Naios
Copy link
Copy Markdown
Contributor Author

Naios commented Feb 13, 2015

The big question is: is it better to swap this in an external tool or include it in the world & bnetserver.

To include it in the servers would bring several advantages like:

  • you need no second install
  • the whole infrastructure is already implemented
  • you can rely on that old updates gets reapplied on change (this would make editing of old (bugged) updates possible),
  • probably it works out of the box if you use the CMAKE_SOURCE_DIR variable.
  • and if you really want to use an external tool you may still disable it in the config.

@Shauren
Copy link
Copy Markdown
Member

Shauren commented Feb 13, 2015

You cannot simply load the entire file into one buffer and execute it as-is. You need to call mysql_set_server_option with MYSQL_OPTION_MULTI_STATEMENTS_ON (preferably opening a separate connection to database with this option for updating purposes)

@DDuarte
Copy link
Copy Markdown
Contributor

DDuarte commented Feb 13, 2015

Yeah, I agree with make the worldserver apply the SQLs instead of an external tool. I linked Jackpoz's proof of concept to show a way to detect changes (it doesn't have to be like this, CRC checks would probably be fine too).

@Naios
Copy link
Copy Markdown
Contributor Author

Naios commented Feb 13, 2015

@Shauren xD you are right, this sql option needs to be set.

And probably it would make sence to open a new connection with this special option, except to set it for all connections.

@DDuarte
Copy link
Copy Markdown
Contributor

DDuarte commented Feb 13, 2015

I need to ask Aokromes for the IRC logs of the discussion of this feature few years ago.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update

@jackpoz
Copy link
Copy Markdown
Member

jackpoz commented Feb 13, 2015

you can rely on that old updates gets reapplied on change (this would make editing of old (bugged) updates possible),

An update is bugged is it throws an error when executed, in any other case a new sql update script should be added instead of modifying the existing one so modified ones shouldn't be updated.
A thing to worry about is sql script renames.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utils.h -> ByteArrayToHexString

@ghost
Copy link
Copy Markdown

ghost commented Feb 14, 2015

as far as i remember mangos used a kind of version check in each sql query. could this be also used in this case here ? well this would mean each sql correction must be pushed as a seperate sql file but this would prevent double batching

@Naios
Copy link
Copy Markdown
Contributor Author

Naios commented Feb 14, 2015

Its requested that queries are multi batchable.

@danlapps
Copy link
Copy Markdown
Contributor

I can clear my DB and launch it couple time if needed, i dont mind resetting everything

@Naios
Copy link
Copy Markdown
Contributor Author

Naios commented Mar 18, 2015

Updated this to a4b5b41. Recent updates (2015_03_16_*) included.

@jaredjones
Copy link
Copy Markdown
Contributor

Well this addition to the core works really well, any reason we're still waiting for it to be merged?

@danlapps
Copy link
Copy Markdown
Contributor

Now time to be a PITA
My SQL server is set as following :
World DBs:
world6
world335
world434

same goes for auth and character so i can keep all 3 branches updated.

Would I be able to set those settings in the automation ?

@Naios
Copy link
Copy Markdown
Contributor Author

Naios commented Mar 20, 2015

@danlapps Sure you can, it updates the dbs that are written in worldserver.conf & authserver.conf/bnetserver.conf.
Normally you use differen't db names there aren't you?

@jaredjones Currently we are waiting to do some cherry-picks first so a new TDB can be released as soon as this gets merged (to avoid conflicts with old not updated TDB's).

@Naios Naios force-pushed the dbupdater branch 2 times, most recently from 6732a8f to 55154d3 Compare March 20, 2015 11:18
@Naios
Copy link
Copy Markdown
Contributor Author

Naios commented Mar 20, 2015

Updated this to a30eb73.

Also added the possibility to define the databases you want to update through flags:
This makes is possible to update only a subset of all available dbs for example world and hotfixes:

#    Updates.EnableDatabases
#        Description: A mask that describes which databases shall be updated.
#
#        Following flags are available
#           DATABASE_LOGIN     = 1, // Auth database
#           DATABASE_CHARACTER = 2, // Character database
#           DATABASE_WORLD     = 4, // World database
#           DATABASE_HOTFIX    = 8, // Hotfixes database
#
#        Default:     15 - (All enabled)
#                     4  - (Enable world only)
#                     0  - (All Disabled)

Updates.EnableDatabases = 15

Also improved the DatabaseLoader which removes a lot of duplicated code in worldserver and bnetserver main.cpp (and adds the functionality to close databases correctly on failure).

    // Load databases
    DatabaseLoader loader("server.worldserver", DATABASE_MASK_ALL);
    loader
        .AddDatabase(HotfixDatabase, "Hotfix")
        .AddDatabase(WorldDatabase, "World")
        .AddDatabase(CharacterDatabase, "Character")
        .AddDatabase(LoginDatabase, "Login");

    if (!loader.Load())
        return false;

@Naios Naios force-pushed the dbupdater branch 3 times, most recently from 6dda07c to ba719fc Compare March 20, 2015 12:12
@danlapps
Copy link
Copy Markdown
Contributor

Yes all DB uses different names, you are a Genius :)

@ghost
Copy link
Copy Markdown

ghost commented Mar 20, 2015

Excellent idea, me gusto. 👍

@DDuarte
Copy link
Copy Markdown
Contributor

DDuarte commented Mar 20, 2015

LF @Naios @ irc

@Naios Naios force-pushed the dbupdater branch 3 times, most recently from a105c81 to b923397 Compare March 20, 2015 23:19
Automatically detects new and edited sql updates through file lists and hashing.
Detects renames, deletes and is able to create and auto import full databases.
* cleanups in main.cpp of world & bnetserver
* refactoring in DatabaseWorkerPool.h & MySQLConnection.cpp

Make sure you re-run cmake, because boost::iostreams was added as dependency.
Maybe you need to install libboost-iostreams1.55-dev on unix as well.

Import every update manual until (included) those INSERT IGNORE updates for each database.

Thanks DDuarte and Shauren for your amazing ideas, help and advises.

In hope that nobody gets a "Your database structure is not up to date..." anymore ,-)

Signed-off-by: Naios <[email protected]>
@DDuarte
Copy link
Copy Markdown
Contributor

DDuarte commented Mar 21, 2015

Merged in 352012e

TODO: Port to 3.3.5

@DDuarte DDuarte closed this Mar 21, 2015
DDuarte added a commit that referenced this pull request Mar 21, 2015
Naios added a commit that referenced this pull request Mar 29, 2015
* Also use proper errno instead of 0 when reconnecting.
* Thanks @et65 for reporting
* ref #14139
Naios added a commit that referenced this pull request Mar 29, 2015
* Also use proper errno instead of 0 when reconnecting.
* Thanks @et65 for reporting
* ref #14139

(cherry picked from commit 4741015)
Naios added a commit that referenced this pull request Mar 29, 2015
Naios added a commit that referenced this pull request Mar 29, 2015
…ysql_init failed.

* Thanks @et65 for noticing.
* ref #14139

(cherry picked from commit 83bbe00)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants