diff -uNr a/bitcoin/manifest b/bitcoin/manifest --- a/bitcoin/manifest ba7d3c68410e33daee3b7745fb530ebe9276e2a35c311eca89e45f9c8527aa06e315efd77006747b21342be6256d81345a78e739ade53ccf21867e2655a07e11 +++ b/bitcoin/manifest 8c2efd9aaefd27e6ced1feb4f81b6172cdab9f0bd2fd842671e338bb4e59fab63f11ce730a70a61538de3957eb66942caaca04fa633c8e78b826eb8ceeeed78b @@ -51,3 +51,4 @@ 735393 bitcoin_posix_error_handling jfw Convert all error codes to readable strings in log and console output. Don't log numeric fork/setsid result in the error case as it's always -1 and only errno is interesting. Translate socket error handling from WinSock to better fit unix-like systems: in particular, EAGAIN may be distinct from EWOULDBLOCK; EWOULDBLOCK and EINVAL don't apply to connect; EINPROGRESS doesn't apply to send/recv; EMSGSIZE doesn't seem to apply to TCP and it's unclear that it could be handled if it did; and errno needs to be saved when there may be intervening libc calls (nAcceptErr). 735838 bitcoin_rebranding jfw Change version string to jwrd.net; apparently even something this simple can't be done without bumping into shoddy earlier work. 833338 bitcoin_reorg_tracing jfw Add more useful log messages for tracking reorganize progress (as well as initial block connection). +833339 bitcoin_db_shutdown_checkpoint_calming jfw Remove various frantic, overdone database-related activities, mostly in the shutdown path where they were doing more harm than good. The goal is to make shutdown fast and somewhat easier to analyze. Checkpointing comes up because it's no longer necessarily done at shutdown. The conditions for periodic checkpoints are simplified; in particular, it's no longer done ~every time a db handle object goes out of scope. Given the use of DB_TXN_WRITE_NOSYNC this means update durability with respect to system crash is somewhat relaxed, but this seems fine given the nature of the application. The size limit on db transaction log files is raised 10x, restoring its earlier value. diff -uNr a/bitcoin/src/db.cpp b/bitcoin/src/db.cpp --- a/bitcoin/src/db.cpp 9bf77e52f028a37eebaf701d3602ebf04c2e1f57cbd358a898f89e160b3da2c7d71d1f5386cbb03520d2e7471857644dd3e5bccd24bf47f3a08657360c3e2a42 +++ b/bitcoin/src/db.cpp 8184aa47fc758c7c623aa3132fefecbe880b17a158dfeea205fee801aec3d32a0379310efebd75fe0faf6ba17c093ef7c9454376fe3c03e1e12081f3f6fc3c97 @@ -87,7 +87,8 @@ printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); dbenv.set_lg_dir(strLogDir.c_str()); - dbenv.set_lg_max(1000000); + // Reverting the reduction in log file size limit from 10MB to 1MB in bitcoin-v0_5_3-db_config.6.vpatch ; that seems to have been an early unsuccessful experiment in avoiding lock resource limits. + dbenv.set_lg_max(10*1000*1000); dbenv.set_lk_max_locks(2737000); dbenv.set_lk_max_objects(1119200); dbenv.set_lk_max_lockers(1119200); @@ -155,15 +156,11 @@ vTxn.clear(); pdb = NULL; - // Flush database activity from memory pool to disk log - unsigned int nMinutes = 0; - if (fReadOnly) - nMinutes = 1; - if (strFile == "addr.dat") - nMinutes = 2; - if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0) - nMinutes = 1; - dbenv.txn_checkpoint(0, nMinutes, 0); + // When a database handle goes out of scope, flush activity from memory pool and disk log to the .dat file if either: + // - 1 minute has passed since the last checkpoint + // - 100 megabytes have been written to the log since the last checkpoint + // "Checkpoints can be quite expensive", says the reference guide, but if not done then the log files accumulate and presumably degrade performance. + dbenv.txn_checkpoint(100*1000, 1, 0); CRITICAL_BLOCK(cs_db) --mapFileUseCount[strFile]; @@ -279,11 +276,9 @@ } -void DBFlush(bool fShutdown) +// This function is now dubiously named; it's now called just once, as part of the shutdown process, after most threads have (probably) stopped. The refcount and empty map checks are left in for now as paranoia. +void DBFlush() { - // Flush log data to the actual data file - // on all files that are not in use - printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); if (!fDbEnvInit) return; CRITICAL_BLOCK(cs_db) @@ -296,25 +291,19 @@ printf("%s refcount=%d\n", strFile.c_str(), nRefCount); if (nRefCount == 0) { - // Move log data to the dat file CloseDb(strFile); - dbenv.txn_checkpoint(0, 0, 0); - printf("%s flush\n", strFile.c_str()); - dbenv.lsn_reset(strFile.c_str(), 0); + // No need to checkpoint here as we do that periodically via DB::Close + // No need to rewrite the whole damn database by calling dbenv.lsn_reset here! This is done elsewhere specifically for wallet.dat to keep it self-contained. mapFileUseCount.erase(mi++); } else mi++; } - if (fShutdown) - { - char** listp; if (mapFileUseCount.empty()) { - dbenv.log_archive(&listp, DB_ARCH_REMOVE); + // No need to remove log files here as we now use DB_LOG_AUTO_REMOVE EnvShutdown(); } - } } } diff -uNr a/bitcoin/src/db.h b/bitcoin/src/db.h --- a/bitcoin/src/db.h fdfe29057eebdd25ed05ec5f7e24489f4a84b11d064e787fc4297b31e872d4dee501050416728c3b2a62ee9b77269dffd04509b3fcad9091a2b63b32f817b32c +++ b/bitcoin/src/db.h c73028563e8c208e55b471758385ae4bcafa2eb3d4b5b6b519de8fd582598e5f9e3d0dcfcd0ac0914ca1a214917affddc1274d27cbba84ab5e39508fe050b272 @@ -28,7 +28,7 @@ extern unsigned int nWalletDBUpdated; extern DbEnv dbenv; -extern void DBFlush(bool fShutdown); +extern void DBFlush(); void ThreadFlushWalletDB(void* parg); bool BackupWallet(const CWallet& wallet, const std::string& strDest); diff -uNr a/bitcoin/src/init.cpp b/bitcoin/src/init.cpp --- a/bitcoin/src/init.cpp 98181df7de317c09aa491d95f0320cbf6afbe8fae3bf8b1bf88457a2309ff67c7e45ac9538e89e2de53a7759e311feb4b13fdba7514acf6a54768b29467d5f34 +++ b/bitcoin/src/init.cpp 495622f455f896aac3529ff002d7eb85b60cf56dd49a732de67eaeb48f59fa61ff721609221a9cec6b4ccf9c4e5794b9580405245d2c622f6e9161d4133e3bce @@ -24,10 +24,6 @@ // Shutdown // -void ExitTimeout(void* parg) -{ -} - void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; @@ -43,14 +39,13 @@ { fShutdown = true; nTransactionsUpdated++; - DBFlush(false); StopNode(); - DBFlush(true); + DBFlush(); boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); delete pwalletMain; - CreateThread(ExitTimeout, NULL); - Sleep(50); + pwalletMain = 0; // paranoia + // unjustified sleep removed here printf("Bitcoin exiting\n\n"); fExit = true; exit(0); @@ -59,7 +54,7 @@ { while (!fExit) Sleep(500); - Sleep(100); + // unjustified extra sleep removed here ExitThread(0); } }