Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The database migrations bug #5198

Open
1 of 5 tasks
sharkykh opened this issue Sep 12, 2018 · 11 comments
Open
1 of 5 tasks

The database migrations bug #5198

sharkykh opened this issue Sep 12, 2018 · 11 comments

Comments

@sharkykh
Copy link
Contributor

sharkykh commented Sep 12, 2018

The bug

During the past 2 database migrations, the databases of some of the users got updated past the "max" database version and some got incorrect values inserted into them.
For example, between v0.2.4 and v0.2.5 we bumped the main DB version from 44.9 to 44.11.
However, during the migration to shift the quality values, some of the users got incorrect values inserted into the databases.
In addition, some users database versions actually got bumped past 44.11, to 44.12, which caused an issue for users when the next database migration landed on v0.2.9.

What happens when Medusa updates?

Currently, after Medusa updates its code either using git pull or downloading the archive from GitHub, it stops the web server and other threads, closes open files, etc.
After that's done, and unless the user had enabled the No Restart option, it spawns a new process of Medusa with the same arguments as the one that was running. (source code)

How does the restart process affect the database migrations?

Due to the use of process monitors or service restarters, which automatically restart a process if it dies, in-conjunction-with Medusa's restart process (with No Restart off),
Medusa is being loaded twice, at the same time, by two separate processes.
The database migrations (try to) execute on both processes at the same time, and in doing so, causing unexpected changes to database entries.

The current Docker configuration (ours, @linuxserver's and possibly others) uses S6 overlay to automatically restart the server inside the container when it dies (source code).
This means that as soon as the original Medusa process dies out, S6 spawns a new one, but Medusa does too, which causes the scenario explained above.
This can be clearly seen in the Docker logs, if you restart Medusa from the web UI, you can see duplicate log messages being logged, and the server tries to bind to the port twice - one of the processes worked, and the other says it can't bind to the port because it's in use, and exits.

It's very possible any other platform that uses a service restarter may have this problem as well.
The Windows installation could also be affected.

What can be done (incomplete)

  • Medusa should not update versions inside Docker containers. Should be implemented with: Feature/enable check runs in docker #5700
  • The Docker container should not be using a service restarter for Medusa at all.
  • Users should be using watchtower to monitor the Docker container's status and update it to a newer version when one is available.
  • We possibly need to set the commit hash and version number when creating Docker images, because when you run a Docker container you first have to update it once using the updater in order for the version checker to work, just like you do when you install using an archive downloaded from GitHub (source code).
  • Medusa's update system needs to be changed to be more configurable.
    We need to be able to conditionally disable updating and checking out branches, but still have the version checking, to notify users of a new version on the web UI in case they don't want to automatically update.

Additional information

  • Docker should only be updated via the container. We should disable the ability for medusa to restart inside of the container and just let docker restart the container instead.

    If users are using watchtower like most do it'll pull the new container, kill the old and rebuild using the new one. It should never change anything in the container after we build it and push to docker hub.

    The reason for this is you should be able to at any stage delete any container or even the whole server and as long as you have the files that you mapped to the container you should be able to fully recreate it on another system. It shouldn't matter about the container.

  • [If we change the Docker container to not be updatable]
    ... The Medusa update system would become useless in the container.
    Right now if you install a new container you have to initialize it by manually updating Medusa, which is problematic.
    And because the commit hash is saved in the config file (and it doesn't use git), if you update outside of Medusa, say - replace the container with a newer version, it would break the update system and will also display incorrect values under Help & Info.

  • Update news about using service restarters - pymedusa/medusa.github.io#117
@udochrist
Copy link

i'm thinking along the lines:

  • inside a docker container medusa should never update itself. the app should however indicate to the user that a new version is available and that the container needs to be restarted to update.
  • stopping and starting medusa inside the container does not trigger any updates at all
  • it should not be necessary to upgrade the docker image to receive a medusa upgrade.
  • the medusa docker container should do an upgrade only when it gets started. This update can be enabled by a settable env-var AUTOUPDATE=true,... in case users do not want to update automatically.
  • a fresh created container always installs or updates medusa. medusa should not be part of the image but installed if its not there.

so:

  • users wanting an upgrade do a stop/start container with the env set to autoupdate
  • users wanting to upgrade on their own schedule do a stop / remove|clean / start

@OmgImAlexis
Copy link
Collaborator

OmgImAlexis commented Sep 14, 2018

  • it should not be necessary to upgrade the docker image to receive a medusa upgrade.
  • the medusa docker container should do an upgrade only when it gets started. This update can be enabled by a settable env-var AUTOUPDATE=true,... in case users do not want to update automatically.
  • a fresh created container always installs or updates medusa. medusa should not be part of the image but installed if its not there.

@udochrist I agree on most of that apart from this. Docker container should be stateless and more importantly immutable. We should be shipping with the software fully installed. To use medusa on any version you should be able to just update the container and the migrations needed would run on start.

@udochrist
Copy link

udochrist commented Sep 14, 2018 via email

@OmgImAlexis
Copy link
Collaborator

OmgImAlexis commented Sep 14, 2018

@udochrist we provide an official container that's built for master and develop branches on merge. It usually takes about 5 minutes for the new images to be pushed.

Edit: Here you are.

@p0psicles
Copy link
Contributor

It shouldnt be any more difficult then having a proper 'universal' method of checking if medusa is run in docker. And disable the autoupdating when detected? Updating the docker image will then upgrade the db on next start?

Or am i missing something?

@udochrist
Copy link

root@34add48022da:/$ ls  -la /.dockerenv 
-rwxr-xr-x 1 root root 0 Sep  8 05:16 /.dockerenv
root@34add48022da:/$ 

That should be the indicator to check for running inside docker currently.

@p0psicles
Copy link
Contributor

Yeah but i don't know if the medusa user will always have access to that. Isn't there something like an env variable?

@OmgImAlexis
Copy link
Collaborator

OmgImAlexis commented Sep 15, 2018

@udochrist
Copy link

@OmgImAlexis what do you mean with "... not 100% of the time"?

docker-ce/components/engine/daemon/initlayer/setup_unix.go
creates it and the / dir with perms 755

@OmgImAlexis
Copy link
Collaborator

@udochrist off the top of my head look at this and this; Things get removed all the time. It'd also make sense not just to fix this for docker but any container runtime it's run in for example running it under lxc.

@p0psicles
Copy link
Contributor

For reference, a log of pymedusa/medusa:develop updating.

2018-11-13 07:56:57 INFO     CHECKVERSION :: [] Checking for updates using SOURCE
2018-11-13 07:56:59 DEBUG    CHECKVERSION :: [] cur_commit = , newest_commit = 0c0a73583452f988c518adeafa75ee1f17987bdf, num_commits_behind = 0
2018-11-13 07:56:59 DEBUG    CHECKVERSION :: [] Unknown current version number, don't know if we should update or not
2018-11-13 07:56:59 DEBUG    CHECKVERSION :: [] Checking GitHub for latest news.
2018-11-13 07:56:59 DEBUG    CHECKVERSION :: [] GET URL: https://cdn.pymedusa.com/news/news.md [Status: 200]
2018-11-13 07:56:59 DEBUG    CHECKVERSION :: [] User-Agent: Medusa/0.2.11 (Linux; 4.4.0-47-generic; ac99bc26-e719-11e8-96bd-0242ac110009)
2018-11-13 07:57:17 INFO     Thread_0 :: [] Config backup in progress...
2018-11-13 07:57:17 INFO     Thread_0 :: [] Config backup successful, updating...
2018-11-13 07:57:19 DEBUG    Thread_0 :: [] cur_commit = , newest_commit = 0c0a73583452f988c518adeafa75ee1f17987bdf, num_commits_behind = 0
2018-11-13 07:57:19 INFO     Thread_0 :: [] Clearing update folder u'/app/medusa/sr-update' before extracting
2018-11-13 07:57:19 INFO     Thread_0 :: [] Downloading update from u'http://github.com/pymedusa/Medusa/tarball/master'
2018-11-13 07:57:19 DEBUG    Thread_0 :: [] GET URL: http://github.com/pymedusa/Medusa/tarball/master [Status: 301]
2018-11-13 07:57:19 DEBUG    Thread_0 :: [] User-Agent: Medusa/0.2.11 (Linux; 4.4.0-47-generic; ac99bc26-e719-11e8-96bd-0242ac110009)
2018-11-13 07:57:19 DEBUG    Thread_0 :: [] GET URL: https://github.com/pymedusa/Medusa/tarball/master [Status: 302]
2018-11-13 07:57:19 DEBUG    Thread_0 :: [] User-Agent: Medusa/0.2.11 (Linux; 4.4.0-47-generic; ac99bc26-e719-11e8-96bd-0242ac110009)
2018-11-13 07:57:20 DEBUG    Thread_0 :: [] GET URL: https://codeload.github.com/pymedusa/Medusa/legacy.tar.gz/master [Status: 200]
2018-11-13 07:57:20 DEBUG    Thread_0 :: [] User-Agent: Medusa/0.2.11 (Linux; 4.4.0-47-generic; ac99bc26-e719-11e8-96bd-0242ac110009)
2018-11-13 07:57:35 INFO     Thread_0 :: [] Extracting file /app/medusa/sr-update/sr-update.tar
2018-11-13 07:57:40 INFO     Thread_0 :: [] Deleting file /app/medusa/sr-update/sr-update.tar
2018-11-13 07:57:40 INFO     Thread_0 :: [] Moving files from /app/medusa/sr-update/pymedusa-Medusa-0c0a735 to /app/medusa
2018-11-13 07:57:41 DEBUG    Thread_0 :: [] Special handling for unrar.dll
2018-11-13 07:57:41 DEBUG    Thread_0 :: [] Special handling for unrar64.dll
2018-11-13 07:57:41 DEBUG    Thread_0 :: [] Special handling for MediaInfo.dll
2018-11-13 07:57:41 DEBUG    Thread_0 :: [] Special handling for MediaInfo.dll
2018-11-13 07:57:42 DEBUG    Thread_0 :: [0c0a735] Notification for Boxcar2 not enabled, skipping this notification
2018-11-13 07:57:42 INFO     EVENT-QUEUE :: [0c0a735] Aborting all threads
2018-11-13 07:57:42 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the DAILYSEARCHER thread to exit
2018-11-13 07:57:42 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the BACKLOG thread to exit
2018-11-13 07:57:42 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the SHOWUPDATER thread to exit
2018-11-13 07:57:42 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the CHECKVERSION thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the SHOWQUEUE thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the SEARCHQUEUE thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the FORCEDSEARCHQUEUE thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the MANUALSNATCHQUEUE thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the POSTPROCESSOR thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the TRAKTCHECKER thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the FINDPROPERS thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the FINDSUBTITLES thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the TORRENTCHECKER thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Waiting for the EVENT-QUEUE thread to exit
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Saving all shows to the database
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Saving config file to disk
2018-11-13 07:57:43 DEBUG    EVENT-QUEUE :: [0c0a735] Broken providers already updated in the last hour
2018-11-13 07:57:43 INFO     EVENT-QUEUE :: [0c0a735] Shutting down Tornado
2018-11-13 07:57:48 INFO     EVENT-QUEUE :: [0c0a735] Restarting Medusa with ['/usr/bin/python', u'/app/medusa/start.py', '--nolaunch', '--datadir', '/config']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants