chainbase icon indicating copy to clipboard operation
chainbase copied to clipboard

add_index() does not use locking

Open cc32d9 opened this issue 6 years ago • 3 comments

I'm using chainbase in Chronicle project in concurrent mode: one process opens the database in read-write mode and is constantly updating it as state history data arrives. Then, multiple read-only processes read from the same shared memory.

I define CHAINBASE_CHECK_LOCKING globally.

I get the following error when read-only client opens the database and defines the indexes:

May 25 01:05:46 sthist chronicle-receiver[5523]: warn  2019-05-25T01:05:46.141 chronicle receiver_plugin.cpp:1201      plugin_initialize    ] 13 N5boost16exception_detail10clone_implINS0_19error_info_injectorISt11logic_errorEEEE: existing index for chronicle::received_block_object has an undo stack (revision range [-1, 23598015]) that is inconsistent with other indices in the database (revision range [23597735, 23597736]); corrupted database?
May 25 01:05:46 sthist chronicle-receiver[5523]: rethrow existing index for chronicle::received_block_object has an undo stack (revision range [-1, 23598015]) that is inconsistent with other indices in the database (revision range [23597735, 23597736]); corrupted database?:
May 25 01:05:46 sthist chronicle-receiver[5523]:     {"what":"existing index for chronicle::received_block_object has an undo stack (revision range [-1, 23598015]) that is inconsistent with other indices in the database (revision range [23597735, 23597736]); corrupted database?"}
May 25 01:05:46 sthist chronicle-receiver[5523]:     chronicle-recei  receiver_plugin.cpp:1201 plugin_initialize

so, there should be a global lock wrapping around add_index(). For now I will wrap the locks around calling add_index in my program, but I think it makes sense to protect it inside chainbase.

cc32d9 avatar May 25 '19 10:05 cc32d9

actually I don't see how this is locking anything. It's not modifying the lock count and not using the read_lock object. Does it work at all?

         void require_lock_fail( const char* method, const char* lock_type, const char* tname )const;

         void require_read_lock( const char* method, const char* tname )const
         {
            if( BOOST_UNLIKELY( _enable_require_locking & _read_only & (_read_lock_count <= 0) ) )
               require_lock_fail(method, "read", tname);
         }

         void require_write_lock( const char* method, const char* tname )
         {
            if( BOOST_UNLIKELY( _enable_require_locking & (_write_lock_count <= 0) ) )
               require_lock_fail(method, "write", tname);
         }

cc32d9 avatar May 25 '19 11:05 cc32d9

as Todd explained in Devs chat, chainbase is not made to be used in concurrent environment. So probably it makes sense to cleanup unused parts in the code to avoid confusion

cc32d9 avatar May 25 '19 19:05 cc32d9

Look like multi process trying to set_revision on same database.

datnguyencse avatar Jan 20 '20 04:01 datnguyencse