diff --git a/src/sqlite3.c b/src/sqlite3.c index ea2fbcb3e067fcb6c20922236ca24a629bb13ce4..37666c3537448a3845f89eb72315663e3c76601a 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -66072,6 +66072,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** so it takes care to hold an exclusive lock on the corresponding ** WAL_READ_LOCK() while changing values. */ +static void printLockInfoWhenReadWal(Wal *pWal); static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ u32 mxReadMark; /* Largest aReadMark[] value */ @@ -66109,6 +66110,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return SQLITE_PROTOCOL; } if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; + if( cnt>=15 ) printLockInfoWhenReadWal(pWal); sqlite3OsSleep(pWal->pVfs, nDelay); } @@ -71028,6 +71030,101 @@ static void pageReinit(DbPage *pData){ } } +static void printLockInfo(unixFile *uFile_db, unixFile *uFile_wal) +{ + sqlite3_log(SQLITE_WARNING, "[printLockInfo] begin\n"); + char *lock_type[3] = {"F_RDLCK", "F_WRLCK", "F_UNLCK"}; + + sqlite3_log(SQLITE_WARNING, "*** DB file ***\n"); + if( uFile_db==NULL ){ + sqlite3_log(SQLITE_WARNING, "NO DB FILE !\n"); + return; + } + int fd_db = uFile_db->h; + + off_t start_list[3] = {PENDING_BYTE, RESERVED_BYTE, SHARED_FIRST}; + off_t len_list[3] = {1, 1, SHARED_SIZE}; + char *lock_name_list[3] = {"pending lock ", "reserved lock", "shared lock "}; + + for(int i=0; i<3; ++i){ + struct flock fl_db; + fl_db.l_type = F_WRLCK; + fl_db.l_start = start_list[i]; + fl_db.l_len = len_list[i]; + fl_db.l_whence = SEEK_SET; + + int ret = osFcntl(fd_db, F_GETLK, &fl_db); + if( ret!=SQLITE_OK ){ + sqlite3_log(SQLITE_WARNING, "osFcntl Fail in DB file!!!\n"); + return; + } + if( fl_db.l_type!=F_UNLCK ){ + sqlite3_log(SQLITE_WARNING, "lock name: %s, pos: 0x%x, len: 0x%x, lock type: %s, owner: %d\n", + lock_name_list[i], start_list[i], len_list[i], lock_type[fl_db.l_type], fl_db.l_pid); + }else{ + sqlite3_log(SQLITE_WARNING, "lock name: %s, pos: 0x%x, len: 0x%x, lock type: %s\n", + lock_name_list[i], start_list[i], len_list[i], lock_type[fl_db.l_type]); + } + } + + sqlite3_log(SQLITE_WARNING, "*** WAL file ***\n"); + if( uFile_wal==NULL ){ + sqlite3_log(SQLITE_WARNING, "NO WAL FILE !\n"); + return; + } + int fd_wal = uFile_wal->h; + off_t start_pos = WALINDEX_LOCK_OFFSET; + char *lock_name_list_wal[8] = {"wal_write lock ", "wal_ckpt lock ", "wal_recover lock"}; + for(int i=3; i<8; ++i){ + lock_name_list_wal[i] = "wal_read lock "; + } + + for(int i=0; i<8; ++i){ + struct flock fl_wal; + fl_wal.l_type = F_WRLCK; + fl_wal.l_start = start_pos; + fl_wal.l_len = 1; + fl_wal.l_whence = SEEK_SET; + + int ret = osFcntl(fd_wal, F_GETLK, &fl_wal); + if( ret!=SQLITE_OK ){ + sqlite3_log(SQLITE_WARNING, "osFcntl Fail in WAL file!!!\n"); + return; + } + if( fl_wal.l_type!=F_UNLCK ){ + sqlite3_log(SQLITE_WARNING, "lock name: %s, pos: 0x%x, len: 0x%x, lock type: %s, owner: %d\n", + lock_name_list_wal[i], start_pos, 1, lock_type[fl_wal.l_type], fl_wal.l_pid); + }else{ + sqlite3_log(SQLITE_WARNING, "lock name: %s, pos: 0x%x, len: 0x%x, lock type: %s\n", + lock_name_list_wal[i], start_pos, 1, lock_type[fl_wal.l_type]); + } + start_pos++; + } + sqlite3_log(SQLITE_WARNING, "[printLockInfo] end\n"); +} + +static void printLockInfoWhenReadWal(Wal *pWal) +{ + printf("[printLockInfoWhenReadWal] begin\n"); + unixFile *uFile_db = (unixFile *)(pWal->pDbFd); + unixFile *uFile_wal = (unixFile *)(pWal->pWalFd); + printLockInfo(uFile_db, uFile_wal); + printf("[printLockInfoWhenReadWal] end\n"); +} + +static void printLockInfoInBusyHandler(Pager *pPager) +{ + printf("[printLockInfoInBusyHandler] begin\n"); + unixFile *uFile_db = (unixFile *)(pPager->fd); + if( pPager->pWal!=NULL ){ + unixFile *uFile_wal = (unixFile *)(pPager->pWal->pWalFd); + printLockInfo(uFile_db, uFile_wal); + }else{ + printLockInfo(uFile_db, NULL); + } + printf("[printLockInfoInBusyHandler] end\n"); +} + /* ** Invoke the busy handler for a btree. */ @@ -71035,6 +71132,7 @@ static int btreeInvokeBusyHandler(void *pArg){ BtShared *pBt = (BtShared*)pArg; assert( pBt->db ); assert( sqlite3_mutex_held(pBt->db->mutex) ); + printLockInfoInBusyHandler( pBt->pPager ); return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); }