Migrace a čistka Subversion repository
Dnešní zamýšlený přesun dočasného Subversion úložiště jednoho projektu na centrální Subversion server se díky dvěma dávným chybám hodně protáhl. Díky tomu jsem si však procvičil práci s repository a uvědomil si záludnosti zálohování Subversion dat.
Prvotní záměr byl velmi jednoduchý - na zdrojovém serveru spustit
svnadmin dump d:\svn_repos\myrepo > d:\myrepo.svn_dump
a na cílovém serveru spustit
svnadmin create d:\svn_data\myrepo --fs-type fsfs
svnadmin load --force-uuid d:\svn_data\myrepo < d:\myrepo.svn_dump
K mému překvapení jsem však v nově importovaném repository objevil záhadné adresáře - viz obrázek. Očekával jsem klasické adresáře /trunk, /tags, /branches, ale místo toho jsem spatřil interní konfigurační a pomocné soubory Subversion repository.
Původně jsem si myslel, že jde o problém přenosu datového úložiště z dočasného serveru, jenž využíval přístupový protokol svn:// na cílový server, který využívá Apache modul a pracuje s https. Proto jsem začal hledat, zdali se nejedná o známý problém. Našel jsem jednoho zoufalce, jenž se potýkal s identickým problémem. Rady, které obdržel, mne velmi překvapily. Prostě mu napsali, že tam některý z jeho uživatelů ty soubory prostě uložil. Silně jsem pochyboval, že by některý z kolegů byl takové pako, aby "komitnul" tyto interní soubory repository, takže jsem se podíval na log, který je v TortoiseSVN velmi dobře použitelný. A opravdu, jednomu z kolegů (nechápu jak) se to opravdu povedlo.
Rozhodl jsem se proto odfiltrovat tyto nežádoucí revize. Při té příležitosti jsem si také vzpomněl, že druhému kolegovi se povedlo omylem vložit do Subversion nezkomprimovaný SQL backup databáze, který byl ihned v následující revizi smazán, takže pouze zbytečně nafukoval velikost Subversion dat. Prvním krokem tak byl export pouze žádoucích dat.
svnadmin dump d:\svn_repos\myrepo > d:\myrepo.svn_dump
Následně příjde ke slovu utilita svndumpfilter.
svndumpfilter include trunk <d:\myrepo.svn_dump >d:\trunked.dump
Dropped 31 node(s):
'/README.txt'
'/conf'
'/conf/authz'
'/conf/passwd'
'/conf/svnserve.conf'
'/dav'
'/db'
'/db/current'
'/db/format'
'/db/fs-type'
'/db/revprops'
'/db/revprops/0'
'/db/revs'
'/db/revs/0'
'/db/transactions'
'/db/uuid'
'/db/write-lock'
'/format'
'/hooks'
'/hooks/post-commit.tmpl'
'/hooks/post-lock.tmpl'
'/hooks/post-revprop-change.tmpl'
'/hooks/post-unlock.tmpl'
'/hooks/pre-commit.tmpl'
'/hooks/pre-lock.tmpl'
'/hooks/pre-revprop-change.tmpl'
'/hooks/pre-unlock.tmpl'
'/hooks/start-commit.tmpl'
'/locks'
'/locks/db-logs.lock'
'/locks/db.lock'
Zbytečné větve tak jsou pryč, nicméně zbývá se ještě zbavit toho omylem vloženého BAK souboru.
svndumpfilter exclude "trunk/adresar1/adresar2/soubor.BAK" <d:\trunked.dump >d:\final.dump
Dropped 2 node(s):
'/trunk/adresar1/adresar2/soubor.BAK'
'/trunk/adresar1/adresar2/soubor.BAK.gz'
K mému překvapení filtr automaticky přidává pravostranné (možná i levostranné) rozšíření, takže došlo i k vynětí souboru, který jsem chtěl v repository ponechat. Nakonec mi nezbylo nic jiného než provést toto.
svndumpfilter include --drop-empty-revs "trunk/adresar1/adresar2/soubor.BAK.gz" <d:\myrepo.dump >d:\correctBAK.dump
Vše je připravené, nyní je třeba dva dump soubory na cílový Subversion server. Nejprve je však třeba vytvořit fyzický adresář a poté založit nové repository.
svnadmin create d:\svn_data\myrepo --fs-type fsfs
Zbývá spustit poslední dva importovací příkazy.
svnadmin load --force-uuid d:\svn_data\myrepo < d:\final.dump
svnadmin load d:\svn_data\myrepo < d:\correctBAK.dump
První příkaz obsahuje --force-uuid, díky tomu budou mít všechny revize stejné ID jako na předchozím serveru. SVN klienti tak budou schopni po relokaci pracovat s kopiemi lokálně uložených dat. Revize jsou korektní s jedinou výjimkou - dodatečný BAK.gz soubor byl přidán až naposled a tudíž v nejnovější revizi.
Při dohledávání informací jsem si uvědomil, že zálohování pomocí svnadmin hotcopy d:\svn_data\myrepo d:\svn_hotcopy\myrepo je sice rychlé, ale záludné - použitelné pro obnovu je to pouze na identické instalaci Subversion (stejné verzi) a stejném operačním systému. Oproti tomu svnadmin dump je sice pomalejší, zato flexibilnější a přenositelný.
Posledním úkonem po přestěhování repository je přesměrování SVN klientů z původního serveru na nový. Toho lze v případě command-line klienta docílit příkazem svn switch --relocate oldurl newurl. V případě používání TortoiseSVN tak lze učinit volbou kontextového menu TortoiseSVN, Relocate...