You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by av...@apache.org on 2019/05/15 15:16:33 UTC
[ignite] 01/01: Squashed commit of the following:
This is an automated email from the ASF dual-hosted git repository.
av pushed a commit to branch ignite-10078-jepsen1
in repository https://gitbox.apache.org/repos/asf/ignite.git
commit ee0ad939b9e56fbc11a7b3bd25bc5c315289915c
Author: Anton Vinogradov <av...@apache.org>
AuthorDate: Wed May 15 18:14:53 2019 +0300
Squashed commit of the following:
commit ca67cc531b1cdfd47f22e949716b43ebd3ae1ca2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed May 15 15:51:54 2019 +0300
IGNITE-10078 Fix several issues.
commit e1f5f4e33b25a6ac4fd1082749d8aae079759799
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed May 8 10:24:27 2019 +0300
IGNITE-10078 Minor codestyle fix.
commit 2c0d7a3b837cc5ce7e2bbe5d712b156dc41a431f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue May 7 10:28:38 2019 +0300
IGNITE-10078 Fix codestyle issues.
commit cda9e5090f5750b78a069b3848049560c56148b2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon May 6 18:51:22 2019 +0300
IGNITE-10078 Disabled RollbackRecord for MVCC caches.
commit 296abfbd886b9ad4fe488a6749803ee5fc9fcf47
Merge: 70b02dec4d 7a42592843
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon May 6 18:30:03 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
commit 70b02dec4dbb41851a976c0d7c41ab2ad065829c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon May 6 16:58:39 2019 +0300
IGNITE-10078 Fix in-memory partition clearing issue, reverted a revert of IGNITE-10799.
commit 3689f9593a7b264617e7c95a309163c9e7ef8c6c
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun May 5 17:41:49 2019 +0300
Revert "IGNITE-10799 Optimize affinity recalculation in case of node join or leave - Fixes #6242."
This reverts commit afe7933b156d51691997fefd251b76de5ea15e1a.
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
commit 83685aa98a1d67334c6d80f025e5495e6d8d9e61
Author: Alexey Scherbakov <al...@gmail.com>
Date: Tue Apr 30 13:05:02 2019 +0300
IGNITE-10078 TC check.
commit d7eeb7fc9fb273eac41b7c297688d65f3c582bbb
Author: Alexey Scherbakov <al...@gmail.com>
Date: Tue Apr 30 11:39:47 2019 +0300
IGNITE-10078 Revert to old initAffinityOnNodeJoin
commit 04114b944d82409d2dcd13f89d4dd79297b87456
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 29 18:44:57 2019 +0300
IGNITE-10078 Fix concurrent isolated updater and tx mode.
commit ec11a9e91b83beddf3a79e6de7484e04cbd1fea2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 29 16:29:26 2019 +0300
IGNITE-10078 Cleanup.
commit 4741ad3267d76e3a7a496926fff534b508f39a5c
Merge: 4a44047cbe 2ad6c85a67
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 29 14:06:29 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
commit 4a44047cbe1f1e44d19e02a401d319799ac452ce
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Apr 28 17:46:13 2019 +0300
IGNITE-10078 Fix issue with cache group name (not properly handled in test code).
commit 15ea64f792f29db3dd88da66b1974df025e1bf2f
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Apr 28 14:55:22 2019 +0300
IGNITE-10078 Fix issue with isolated updater.
commit d05fb3f0971a62097d28ef52de1ecd41309d61d4
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sat Apr 27 15:30:50 2019 +0300
IGNITE-10078 Partial revert of affinity calculation optimization on node left.
commit 1c4a20a7276eefc5f2da6decc580bef6eb1bbfd7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 26 19:12:39 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
commit 349e8d6d6603fb6b82e3ba14b8178a7be0b70ece
Merge: 19ca96fa9c a998b25828
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 26 19:11:43 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
commit 19ca96fa9ce8c25eed0d047b8d0f8a069e58a96e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 26 18:51:43 2019 +0300
IGNITE-10078 Minor.
commit e2a44a3c989abe1db59759a0ed742f022f569a7f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 26 18:49:36 2019 +0300
IGNITE-10078 Final codestyle fix.
commit 25dc10a2b87b65fb80df80ff331893a89cd177e9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 26 17:39:42 2019 +0300
IGNITE-10078 Fix wrong late affinity calculation.
commit a31aaa18abaed5f5e590ed4c7fc2a3d205a9f4f9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 25 19:59:18 2019 +0300
IGNITE-10078 Cleanup.
commit 7d41dba297ac11cf9ced030e634e05cd3aed641d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 25 19:16:37 2019 +0300
IGNITE-10078 Cleanup.
commit cf11881fb1a5f22ca6624389ad661a3f7b9a4aa7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 25 18:21:01 2019 +0300
IGNITE-10078 Cleanup.
commit 3b265806d61a5d5b25f50c4920eeb858a196578a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 25 16:35:06 2019 +0300
IGNITE-10078 Cleanup.
commit 03dbe7cd0fdbb969b38647b43fbbca9476b2c869
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 25 14:41:53 2019 +0300
IGNITE-10078 Fix CacheGroupTest scenarios with mixed tx-atomic caches in groups.
commit 6980832cbf5dd00b964a9e2f6a87229f542a53e9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 24 18:47:32 2019 +0300
IGNITE-10078 Fix issue with isolated updater in test.
commit 6860fa3b3df0e1179ec63b55ba1ded4c79fcf61a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 24 18:01:35 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsContinuousRestartTest.java
# modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
commit be160d5edf77853de47a323b5519bc283aebc1dd
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 24 15:05:44 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsContinuousRestartTest.java
# modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
commit 05e1df5d507bd0a6af302cd463cf14de00d09a98
Merge: 4ccae674c3 c2c0b148ae
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 24 15:05:32 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsContinuousRestartTest.java
# modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
commit 4ccae674c3ad14e994d4c3600e2f9bed3224f34a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 24 14:50:00 2019 +0300
IGNITE-10078 Cleanup TODOs.
commit 6223cb2518b00defd6f47ebfef1feae7ded16fbb
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 23 20:35:40 2019 +0300
IGNITE-10078 Cleanup TODOs.
commit 3e7da5ab7867f08052676f1939c903dde35ef71e
Merge: e48ce33e4d db285122a7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 23 15:54:29 2019 +0300
Merge branch 'ignite-10078' of https://github.com/gridgain/apache-ignite into ignite-10078
commit e48ce33e4d000221aebc78ec0e053f3c096f00c6
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 23 15:53:41 2019 +0300
IGNITE-10078 Implemented "old mode" for atomic or mixed cache groups.
commit db285122a76c86f9f0a171ad64728473ead69468
Author: Alexey Scherbakov <al...@gmail.com>
Date: Mon Apr 22 23:34:03 2019 +0300
IGNITE-10078 Fix NPE in exchange future.
commit 3cc00ab8f6b77982c3da8c82f20f014250a0929c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 22 17:58:01 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite3.java
commit 9062305f0ed4860904d5c4a6a24dd181e8af8dc1
Merge: 60fc9b26d3 d6827886a4
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 22 17:57:48 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite3.java
commit 60fc9b26d3dfd798611094bc67d2047a6aa5da23
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Apr 21 18:56:16 2019 +0300
IGNITE-10078 Fix issue with re-rebalance of moving partition on coordinator.
commit 7b2b7dbf074841090bebb9dc48f5b02121172fad
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 19 19:30:05 2019 +0300
IGNITE-10078 Proper fix for clearing partition + full rebalance.
commit 165a4d17ec97b92f90ea4a19a89108bc1589b1e3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 19:50:14 2019 +0300
IGNITE-10078 Cleanup - wip.
commit b8a97b78a2ab81eeb8a5136b58bb31d99d0b91e8
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 18:48:57 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/DefaultFreeList.java
commit 030b4606a938d41151303878a71396ef0f5eb38c
Merge: 204202826e 280894315f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 18:44:15 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/DefaultFreeList.java
commit 204202826ee5a7cc261d8b8107b51f26dc0e7ea3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 17:51:14 2019 +0300
IGNITE-10078 Minor style.
commit 13a89dd7aa3c472cef427e84bc2c63ceb5401865
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 17:23:58 2019 +0300
IGNITE-10078 More logging for flaky test CacheRentingStateRepair.
commit 60da22ae7ca84b0e83fc7d235d2a8bd07cb92292
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 17:21:26 2019 +0300
IGNITE-10078 More logging for flaky test CacheRentingStateRepair.
commit 069842550d674e7fa28938b4f3f61389b174ffd2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 13:17:41 2019 +0300
IGNITE-10078 Extending expected exceptions list in continuous restarts test.
commit f779e293dc687f50e0db4645a7c7f9ba6d234907
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 18 12:01:44 2019 +0300
IGNITE-10078 Extending expected exceptions list in continuous restarts test.
commit a5609b1585fa6efec058736b1c489776532ad229
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 17 20:20:30 2019 +0300
IGNITE-10078 Ignore flaky test.
commit 88429164db2405d920418390fe88b358654bdbc1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 17 20:15:55 2019 +0300
IGNITE-10078 Fix data store init on activation.
commit 41c0ef30f54d7378a1dccef5b94ff2b89f847715
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 15 20:02:12 2019 +0300
IGNITE-10078 In-place update fix, improved logging for rebalance.
commit d7686fee1b8285b89cacbd561c53721679568984
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Apr 14 21:54:32 2019 +0300
IGNITE-10078 Disabled debugging counter for TC run.
commit 31df1cbc6890a94e82796dc3558693caef0ab665
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Apr 14 19:31:03 2019 +0300
IGNITE-10078 Valid late assignment switch.
commit cbd4e0cfc0b00858412f97962998e3a22e64d6e6
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 12 19:07:22 2019 +0300
IGNITE-10078 minor renaming.
commit 27c5c8e4904430a8733fa0e0e750ed23b8c9f691
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 12 18:14:17 2019 +0300
IGNITE-10078 Fix for force clearing partition if was in moving state before rebalance.
commit 40e88354d64aad4f44e76faf5d3d0be4278efd14
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 12 15:30:50 2019 +0300
IGNITE-10078 Desync on full rebalance reproducer.
commit b7a9dd115711b15fb04a8cf2e6859aeab246d105
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 11 15:07:33 2019 +0300
IGNITE-10078 Additional logging.
commit 4a4979c57e2ac876e455c1742ed86e2aa1512bf5
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 9 19:20:13 2019 +0300
IGNITE-10078 Additional logging.
commit 9ca272222ebc80f87b08c9527db42a2b6352813b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 9 18:43:40 2019 +0300
IGNITE-10078 Desync fix test 3.
commit a21cce2b2922b71c8cc559ee7be31c3b82ea9636
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 9 18:21:42 2019 +0300
IGNITE-10078 Desync fix test 2.
commit aea2d5cdf02adc11ce7870b7d2515e8a10330e5a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 9 15:49:49 2019 +0300
IGNITE-10078 Desync fix test.
commit a27761d262f840890cd01b57ff16e537596fd114
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 8 19:34:51 2019 +0300
IGNITE-10078 Reproducer for desync + hist rebalance issue.
commit 048b0a68583ccc1de94afa6f7961bcbd9ddb14b6
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 8 18:32:22 2019 +0300
IGNITE-10078 Fixed concurrency issue.
commit 109ef03f46b5075612b789afe4ab3a1e6ee675f8
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 5 18:01:58 2019 +0300
IGNITE-10078 Cleaned up tests.
commit d7a48d6873ab3075d1bafcd1699512a9aabd1cb3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 5 16:30:29 2019 +0300
IGNITE-10078 Disable removal from deferred queue on rebalance by ttl.
commit ee3306749d993d7534ba2abb2f29a06cf48ca219
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 5 14:18:26 2019 +0300
IGNITE-10078 Next fix try.
commit 29565048837a952928e7a3e4796161677dda2cdc
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 5 14:16:16 2019 +0300
IGNITE-10078 Next fix try.
commit 8ee04285948e3d3f1b9e913aa41c7cb4b78e3ada
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 5 13:56:45 2019 +0300
IGNITE-10078 Reproduced desync issue.
commit 560341ec7fc665e3bc08eebe817eb6b1e20d41df
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Apr 5 11:47:20 2019 +0300
IGNITE-10078 Test deferred queue fix.
commit b9ab5bdde2babd2e52c0d06f36d0900feda0049e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 4 19:04:18 2019 +0300
IGNITE-10078 WAL reader.
commit a55854aa6bda5bbd4c0ae5bd3303c8808ae2a984
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 4 17:51:28 2019 +0300
IGNITE-10078 Added test for scenario when missed update is received after checkpoint.
commit 5bc28b8e392b7202da1cfa96fd53830a96b404c7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Apr 4 17:51:09 2019 +0300
IGNITE-10078 Added test for scenario when missed update is received after checkpoint.
commit 8019f91cf0d4619225dbeb5a20d54d29d4a74d1b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 3 20:15:52 2019 +0300
IGNITE-10078 Fix logical recovery issue with zero counter.
commit 63eff8ed8160b9498cb38e3f64125a237e3de219
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Apr 3 18:47:14 2019 +0300
IGNITE-10078 Use rollbackrecord on logical recovery to avoid unnecessary rebalancing.
commit c0e7d577149fdb65e918af6d3a33423ce7edcb9a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 2 11:54:53 2019 +0300
IGNITE-10078 Fix naming for out-of-order updates.
commit 2f85c2c91ea3726dbcfc73294189db1bd5a28742
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 2 11:44:20 2019 +0300
IGNITE-10078 Pre-create partition only if having valid state.
commit eb911681d38e9ef437428c31e6e304ea22276376
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Apr 2 10:50:24 2019 +0300
IGNITE-10078 Minor.
commit 9eeb2dcc0eb6e6e27139935bcb9e240cfb3b110d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 1 20:18:33 2019 +0300
IGNITE-10078 Added assertion for sequential partition.
commit 46a89b1dd65443d9f9f180e2438cb458a52d3577
Merge: ab14a8ec9f 963a40b7aa
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 1 14:55:09 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit ab14a8ec9f56d1b97f274f54d0dbbfae66fe7ccd
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 1 14:53:58 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
commit 196b9f2bf83b44e55cfc9f599aedf7b7cd1da25e
Merge: 4b9301c439 9a9c817f8f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 1 14:53:38 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
commit 4b9301c43919c50472f96a1b529eef66b96daeeb
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Apr 1 12:08:11 2019 +0300
IGNITE-10078 Minor code cleanup.
commit 237ffd0b1b9084ec73af395d8a072c1173fec2bf
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Mar 31 19:32:49 2019 +0300
IGNITE-10078 Partition update counter debugging.
commit c832ab48533547cb3179d3b537c7c9061b8b6642
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Mar 24 15:41:46 2019 +0300
IGNITE-10078 Fix update counter overlap issue.
commit 2a8f9dd5366efb2b6a49ef8b066e3971eb3a6d5f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 22 19:22:56 2019 +0300
IGNITE-10078 Cleanup TxPartitionCouterState* tests.
commit 473f7b7a1ea7b0a2ae19272bf482354f5f1309c5
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 22 17:56:30 2019 +0300
IGNITE-10078 Cleanup TxPartitionCouterState* tests.
commit 7021afe4655cc9458401e90475fc6920134f4f4e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 22 16:22:46 2019 +0300
IGNITE-10078 Cleanup TxPartitionCouterState* tests.
commit 6184535280a7365466691cd8831980f7c03f5df5
Author: Alexey Scherbakov <al...@gmail.com>
Date: Thu Mar 21 23:02:03 2019 +0300
IGNITE-10078 Fix wrong test.
commit 20ab7b99ff73c811a7e354e3cc63a910bdf17eb0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 21 19:09:33 2019 +0300
IGNITE-10078 Fixed test.
commit ebe1e51e286dfb71683fbbf92d7d7733a6df8b29
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 21 16:25:24 2019 +0300
IGNITE-10078 Fixed new record type and gaps shring issues.
commit 556fe9070d7f4a74cd7c08fd6dcb69e0d7787ecf
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 21 11:38:13 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
# modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
commit 2c876b7a0063ea3fcff80cbf16dd66b63c825713
Merge: f802c53c0c b221ab8dd1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 21 11:37:24 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
# modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
commit f802c53c0c15face1035d3616ca4ec3231dfa171
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Mar 20 19:42:08 2019 +0300
IGNITE-10078 Fixed issues in partition metastore. Removed copypaste.
commit 2400675fe8698dfc364a7efba515a599c07f3351
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 19 20:52:05 2019 +0300
IGNITE-10078 Add partition metastore.
commit 9b1a06b2e24881a34052b73c6266dc61bf8f2bbb
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 19 19:29:39 2019 +0300
IGNITE-10078 Add partition metastore.
commit 59aa188edf14dc51186b457afb309bf032f272b6
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 19 19:13:38 2019 +0300
IGNITE-10078 Add partition metastore.
commit 55c6f7cbba1df258704772264302cd2c6da5b0b0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 18 20:03:50 2019 +0300
IGNITE-10078 Fix wrong (partially) assertion.
commit ac2cff4c742cccd0287434fc06cf02daa7ff418b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 18 14:38:30 2019 +0300
IGNITE-10078 Fix metastore default partition.
commit 725c0ea33a31b8cc87b510dc7f0ecf0e63247f68
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 18 11:27:18 2019 +0300
IGNITE-10078 Minor.
commit 7af2cef3dbae5dd7da355986c321019a836f88e4
Author: Alexey Scherbakov <al...@gmail.com>
Date: Mon Mar 18 00:32:24 2019 +0300
IGNITE-10078 Fix freelist issue.
commit 0dc46d6296a603c2bba93e6d055f60457cb750e4
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Mar 17 20:50:46 2019 +0300
IGNITE-10078 Fix freelist issue.
commit 73880630a11733cecf80b49b661576bac9e49aff
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 15 19:15:31 2019 +0300
IGNITE-10078 Fix concurrent modification issue for gaps.
commit 7880d721d8543c01cc40ff766c268133fcb02741
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 15 16:11:48 2019 +0300
IGNITE-10078 Code style.
commit 304ea22552a8f545ffbcdea1618a42f56bec9814
Merge: cff5b4e4d0 ee172d2604
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 15 15:53:13 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
commit cff5b4e4d05bbfcaff84533c6798460c9be12878
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 15 15:43:30 2019 +0300
IGNITE-10078 FreeList refactoring.
commit 70024029c8f27c76ed70d72867c3220ab9c21112
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Mar 15 15:25:47 2019 +0300
IGNITE-10078 FreeList refactoring.
commit 843c84b5994697f3f01d1eb2039680a0c0384139
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 14 20:31:54 2019 +0300
IGNITE-10078 FreeList refactoring.
commit eb6e9a303947d831419fc8cb5750b3e4a38102c6
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 12 20:05:34 2019 +0300
IGNITE-10078 FreeList refactoring.
commit 1530626b8f4836a5f2b6b80a467d25f85a5c468d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 12 14:19:56 2019 +0300
IGNITE-10078 FreeList refactoring.
commit 7feed34f26b467225beb4515d71d0ec97decba0b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 12 14:18:05 2019 +0300
IGNITE-10078 FreeList refactoring.
commit 76d367098ec8854b2c9d0121c1d798bd8f2e3724
Author: Alexey Scherbakov <al...@gmail.com>
Date: Mon Mar 11 21:52:57 2019 +0300
IGNITE-10078 Refactoring freelist to work with any Storable.
commit b747416898445e5f502f404ba2973867872f1186
Author: Alexey Scherbakov <al...@gmail.com>
Date: Mon Mar 11 16:51:48 2019 +0300
IGNITE-10078 Added local cache tx test to ignored for MVCC.
commit 20634d470e922fa2a5268cec4be49ddf3e4bf8a9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 11 13:31:58 2019 +0300
IGNITE-10078 Javadoc cleanup.
commit 50394ae2d2b535a4f0757133e4c7508293cd956d
Merge: 7ace0b5be5 3e80ca44e4
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 11 12:11:46 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit 7ace0b5be5ee5d1026b2fe9fe7267de6ecd38a97
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 11 12:04:08 2019 +0300
IGNITE-10078 Removed local cache tx test from MVCC suite.
commit 96c492bc642fb0ff8bf2efd7fde56c68a3f152a8
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Mar 10 20:58:57 2019 +0300
IGNITE-10078 Fixed mixed local and dht tx.
commit 1e5796cfb4a8718d5d7fca3f7b050dbe99535615
Author: Alexey Scherbakov <al...@gmail.com>
Date: Fri Mar 8 20:00:10 2019 +0300
IGNITE-10078 Cleaned up tests with all owners restart in the middle of tx.
commit 29b87e76545f9a07b1ea53b01edd3e0f5bb9bf89
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 7 17:18:19 2019 +0300
IGNITE-10078 Added fail all test for history rebalance.
commit 57ff05af9f00cc53ed829329e2b02e4e09c58b38
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 7 17:02:30 2019 +0300
IGNITE-10078 Cleaned up restart all on partial commit test. Property for failing nodes on counter inconsistency.
commit 2b30ec1aaae0b6328a802d801af656ca700afc33
Merge: 8d39aab13b cfa12b19fa
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Mar 7 10:50:11 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit 8d39aab13b8ac604ea30addd8cb9b13376699f2e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Mar 5 13:17:52 2019 +0300
IGNITE-10078 Change counter generation for mvcc mode to not use reservation mode.
commit 4a57bbdf6037df2c46f8f77cb67d3d42ad4dc76e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 4 19:48:23 2019 +0300
IGNITE-10078 Cleanup.
commit 63ba1379e2edd8bc6f87b3116295326c4674dec3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 4 17:23:05 2019 +0300
IGNITE-10078 Removed unneeded code.
commit 0cd54d08722b12f9d25559c5f54d593a2434dbb0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 4 17:19:11 2019 +0300
IGNITE-10078 Removed unneeded code.
commit f21879a780f9320b4db4a75170473c84122bfee2
Merge: ed202a97cc 6008a0af5f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Mar 4 16:12:52 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit ed202a97ccc7314ed0f7ab51285ebf2634a93e67
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Mar 3 21:44:20 2019 +0300
IGNITE-10078 wip.
commit 91b5c27ff774e5eba799846fa570bf615c3a68c5
Merge: 949abb2e01 7100b05d96
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Mar 3 13:20:23 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit 949abb2e01f6154adbd56458a3e5e29361a7ea07
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 28 20:37:53 2019 +0300
IGNITE-10078 removed commons-cli dep, uncommented mvcc tests.
commit b416274f1d4bce8586e157d70d2515054b7efbd9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 28 20:01:37 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedTtlCleanupManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/PartitionCountersNeighborcastFuture.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheLocalTxStoreExceptionSelfTest.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsContinuousRestartTest.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite1.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite2.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite3.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite4.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite5.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite6.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite7.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite8.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite9.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
commit 4f9f9db63579129c3039a9c77c1982c95b25c3f9
Merge: 82869a6569 efc6b96578
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 28 19:36:44 2019 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedTtlCleanupManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/PartitionCountersNeighborcastFuture.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheLocalTxStoreExceptionSelfTest.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsContinuousRestartTest.java
# modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryFailoverAbstractSelfTest.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite1.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite2.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite3.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite4.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite5.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite6.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite7.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite8.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheMvccTestSuite9.java
# modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite9.java
commit 82869a65696545370aacb10ce053446694ec809c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 28 17:30:20 2019 +0300
IGNITE-10078 wip.
commit a9a8f60163511a0bc150ee00cff05125b36eb670
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 28 17:27:08 2019 +0300
IGNITE-10078 debugging memleak.
commit 86d1505501b25765cabf50f48b2793317aa181c7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 28 13:39:32 2019 +0300
IGNITE-10078 debugging memleak.
commit 63575fd7e028079058b38c924bbe5baa68663c54
Author: Alexey Scherbakov <al...@gmail.com>
Date: Wed Feb 27 21:23:25 2019 +0300
IGNITE-10078 wip.
commit fd39008ae713fd024ed2f9104865442a36af3144
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Feb 27 19:03:49 2019 +0300
IGNITE-10078 debugging memleak.
commit 9dc944768108dbef274b3e10268b2be701df53c9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Feb 27 18:58:19 2019 +0300
IGNITE-10078 debugging memleak.
commit 5cc20becc77161e0f59a612721f928b909f609ee
Author: Alexey Scherbakov <al...@gmail.com>
Date: Wed Feb 27 09:28:12 2019 +0300
IGNITE-10078 wip.
commit 08f4612f2224cbc7df1b947e54b6bcd153c88759
Author: Alexey Scherbakov <al...@gmail.com>
Date: Wed Feb 27 00:51:29 2019 +0300
IGNITE-10078 wip.
commit 9e8bf896ebbb9079441ab65092c42bd016b164e1
Author: Alexey Scherbakov <al...@gmail.com>
Date: Mon Feb 25 22:52:46 2019 +0300
IGNITE-10078 wip.
commit 8273eafe35b0f93c57cee20a4bd8a36de0434860
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Feb 25 18:00:25 2019 +0300
IGNITE-10078 wip.
commit 8288ba34a8e41a13ed92f66400aaa6fb29a0fcca
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Feb 24 19:28:57 2019 +0300
IGNITE-10078 wip.
commit 20d052268c27da3492e795cfeb38000921b7c83c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Feb 20 19:30:08 2019 +0300
IGNITE-10078 wip.
commit e48cd10c562d780ce54100be26611ace644fbaa6
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Feb 17 21:34:52 2019 +0300
IGNITE-10078 wip.
commit 7f67efd960e2d5333cf0574f38d2154671c67e13
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Feb 17 18:30:44 2019 +0300
IGNITE-10078 wip.
commit 9fa1128e22be21d88cd0e600232b7aa7148b7dca
Author: Alexey Scherbakov <al...@gmail.com>
Date: Sun Feb 17 18:18:32 2019 +0300
IGNITE-10078 wip.
commit 9b6d2e67c2940579f95cd32b08cc0f75131f883d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Feb 15 19:33:43 2019 +0300
IGNITE-10078 wip.
commit 6ef3ddfe7291aa301090f5466ee44a7e1c475769
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Feb 14 16:41:30 2019 +0300
IGNITE-10078 wip.
commit aedadfbddae26807b3c8710c75bab3f7f5c52f1e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Feb 12 16:00:26 2019 +0300
IGNITE-10078 wip.
commit 5b46f2cd69ed32b12f6745eca46ace1940b82436
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Feb 12 15:54:43 2019 +0300
IGNITE-10078 wip.
commit 3d656cb3d7bcd7bd806c100ace10964585505376
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Feb 11 15:58:09 2019 +0300
IGNITE-10078 wip.
commit f3a9ae136df9c3867887e77da2630a7c88b74340
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 30 19:37:34 2019 +0300
IGNITE-10078 wip.
commit 51b420a3493a39ed1cc890e423f61915a404b9a5
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Jan 28 20:07:52 2019 +0300
IGNITE-10078 wip.
commit d35ba43b4dc18cde5bfb5891b59dd55b38814529
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Jan 25 19:35:43 2019 +0300
IGNITE-10078 wip.
commit 2435f3855692c7e359f752ad6ff734fb3a3eb9c3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Jan 25 12:05:08 2019 +0300
IGNITE-10078 Implement read only counters to avoid unnecessary storage init.
commit 1eab30f08e14bc0c6e519dbd9b1efe97173dd2f1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 23 19:27:35 2019 +0300
IGNITE-10078 wip.
commit e4ac96856ae975856acd5a67761ddd2ebc20ab56
Merge: b56a1b4422 15cefeabe1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 23 19:27:22 2019 +0300
IGNITE-10078 wip.
commit b56a1b442232358e1754e5ade92bbf4fc2e7ff22
Author: ascherbakoff <al...@gmail.com>
Date: Sun Jan 20 20:33:03 2019 +0300
IGNITE-10078 wip.
commit 1aaab90c9329910e906eeb3e01eb23381d77adde
Author: ascherbakoff <al...@gmail.com>
Date: Sun Jan 20 17:35:03 2019 +0300
IGNITE-10078 wip.
commit 7bde03c5a98f229277a98bad76a3bcb95fcb0530
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Jan 14 19:56:15 2019 +0300
IGNITE-10078 wip.
commit e5da1e699595089b9a999ecde134a570ecc50637
Author: ascherbakoff <al...@gmail.com>
Date: Sun Jan 13 21:30:03 2019 +0300
IGNITE-10078 wip.
commit 18cb5c844aef1230892a42fc034a09546686f96d
Author: ascherbakoff <al...@gmail.com>
Date: Sun Jan 13 20:11:27 2019 +0300
IGNITE-10078 wip.
commit f2b8509559118fb7ba4d1e9b7fc5d8c069b0e578
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Jan 10 15:12:33 2019 +0300
IGNITE-10078 wip.
commit 6858d29c24610c4d318ce698248ac98aa52034d9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 9 20:11:53 2019 +0300
IGNITE-10078 wip.
commit 06922c86c9d75a85780d3755dacb6a8ebb526c73
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 9 18:19:24 2019 +0300
IGNITE-10078 wip.
commit bd658cdc017d56d0954b90966ccb6577753b7131
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 9 17:58:31 2019 +0300
IGNITE-10078 wip.
commit a6841c4f59a76475b9fafcb75bc5552a0da5e117
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Jan 9 17:41:11 2019 +0300
IGNITE-10078 wip.
commit deb7c1a170c1ed7365523cb42c2c8781d2cf8a4e
Author: ascherbakoff <al...@gmail.com>
Date: Tue Jan 8 21:30:29 2019 +0300
IGNITE-10078 wip.
commit 9375a0c1147b69cf3e5eb959248d9a101a89448e
Author: ascherbakoff <al...@gmail.com>
Date: Mon Jan 7 21:29:29 2019 +0300
IGNITE-10078 wip.
commit dc25d341d50f4dbc49f0afa9f409732d48a96393
Author: ascherbakoff <al...@gmail.com>
Date: Mon Jan 7 21:27:17 2019 +0300
IGNITE-10078 wip.
commit 4aedc9f113e4b1ce81cc22b4812dc343022dd7e8
Author: ascherbakoff <al...@gmail.com>
Date: Sat Jan 5 22:07:32 2019 +0300
IGNITE-10078 wip.
commit 233fa73a5c2dc148433b1c4a62c73daf1643e175
Author: ascherbakoff <al...@gmail.com>
Date: Sat Jan 5 22:07:18 2019 +0300
IGNITE-10078 wip.
commit d349054573203b696f7194fd5d60d20c6136219e
Author: ascherbakoff <al...@gmail.com>
Date: Sat Jan 5 16:45:51 2019 +0300
IGNITE-10078 wip.
commit b4ee593ae7a63b4c2384cca8be6445c402a2c88a
Author: ascherbakoff <al...@gmail.com>
Date: Fri Jan 4 20:32:57 2019 +0300
IGNITE-10078 wip.
commit c0ac8df87163626e73b5b0a9cc7f9bb81ffefd62
Author: ascherbakoff <al...@gmail.com>
Date: Fri Jan 4 20:30:52 2019 +0300
IGNITE-10078 wip.
commit 6e31e7379e9597ace892b37c1e9db06be37369db
Merge: 30393a15f6 bd6bc433bc
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Jan 4 20:20:59 2019 +0300
IGNITE-10078 wip.
commit 30393a15f6e848096490ca50de75ab0ad7f60da8
Author: ascherbakoff <al...@gmail.com>
Date: Fri Jan 4 19:57:04 2019 +0300
IGNITE-10078 wip.
commit 78b976ba29a54322fb77978dd837d1235f9f956c
Author: ascherbakoff <al...@gmail.com>
Date: Fri Jan 4 19:55:34 2019 +0300
IGNITE-10078 wip.
commit b71bb041e634da4f5498b483b6cf0b616a310f16
Author: ascherbakoff <al...@gmail.com>
Date: Wed Jan 2 17:16:37 2019 +0300
IGNITE-10078 wip.
commit 4e395780f2e930832ddb6af256bd9960ba34e56e
Author: ascherbakoff <al...@gmail.com>
Date: Fri Dec 28 16:59:46 2018 +0300
IGNITE-10078 wip.
commit 7f57adc354054d8a176d6abdfa191472d86d23da
Author: ascherbakoff <al...@gmail.com>
Date: Fri Dec 28 13:26:28 2018 +0300
IGNITE-10078 wip.
commit 78b7b21544ae18dffcbd28e11d870fb4e87e8968
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 19:04:07 2018 +0300
IGNITE-10078 wip.
commit 458b9afdc28e318f6f1e2d84a482e6db56f89e0c
Merge: 806f33ea32 ca71fe9ba1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 19:03:22 2018 +0300
IGNITE-10078 wip.
commit 806f33ea327669874bfc55a1c3ab8b2f336df05e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 18:23:46 2018 +0300
IGNITE-10078 wip.
commit 0f4ea2945da15b8f05fd8c552ff49ff54bc49083
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 18:13:50 2018 +0300
IGNITE-10078 wip.
commit f6408cb2335bc7a59237c38f405ea7fa18147ea1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 17:33:41 2018 +0300
IGNITE-10078 wip.
commit 804f15318e3c8843125b1c666559fea217df958b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 17:11:22 2018 +0300
IGNITE-10078 wip.
commit bc90e89f9f02116cb481b18067f77cfb1b667333
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 17:06:57 2018 +0300
IGNITE-10078 wip.
commit 70e055bc445e21ecade2674ff3f6afe0778e42f7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 16:27:54 2018 +0300
IGNITE-10078 wip.
commit 5c43d5b85676b9d2e9773aa660fc026b69b76746
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 27 15:50:08 2018 +0300
IGNITE-10078 wip.
commit 77b244819fcd3d60089dcca1919e79a12ade1e2e
Author: ascherbakoff <al...@gmail.com>
Date: Wed Dec 26 23:18:06 2018 +0300
IGNITE-10078 wip.
commit b7aadbe362ff10e12fa45366a95450eb6dfb5139
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 20:58:34 2018 +0300
IGNITE-10078 wip.
commit 5d348022d338643c3fb083f98fe2a3f3e8dd9902
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 20:47:02 2018 +0300
IGNITE-10078 wip.
commit 37056a266068007833ede53dddaad133a5ceda52
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 20:24:36 2018 +0300
IGNITE-10078 wip.
commit a4f05d7c0fd2380694358d7e74ddb86ccc5dafec
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 18:07:28 2018 +0300
IGNITE-10078 wip.
commit ba12e3eea5eba72ad934b8ea9c29c7d9cd620be1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 17:23:32 2018 +0300
IGNITE-10078 wip.
commit 1c2fa92b3038b151e504d22884d53d54c590dc85
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 17:05:27 2018 +0300
IGNITE-10078 wip.
commit 1f5f06922feaa8719e227df9b7258511e21ddcb8
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 13:38:29 2018 +0300
IGNITE-10078 wip.
commit cad6c2bf2180c528486333f0dc4538b3b4f9ff13
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 26 11:45:58 2018 +0300
IGNITE-10078 wip.
commit ba6332c328ea9fe30781e6a5cc1115380a71857b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 20:44:13 2018 +0300
IGNITE-10078 wip.
commit 897a527e79bda8125c777d8fda9a595074c350eb
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 20:40:17 2018 +0300
IGNITE-10078 wip.
commit ef371035ba5ff530e74962846731ec7791aa20ec
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 19:49:26 2018 +0300
IGNITE-10078 wip.
commit 5b24857533ec3fa4b8f6e767cc148e964f5cfe07
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 19:46:40 2018 +0300
IGNITE-10078 wip.
commit 158c1649562469257d7b32c7854d88cfbae46dcc
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 17:15:54 2018 +0300
IGNITE-10078 wip.
commit 1960c4b2e88069210fc2acbb8d49abe46c4328a7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 17:03:40 2018 +0300
IGNITE-10078 wip.
commit ecabcf35bc124ab66b4027096724a994d3cd6b56
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 25 11:56:50 2018 +0300
IGNITE-10078 wip.
commit 0c3d2c9315b0577a878f94a8934f966ce25c6cc9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 24 18:47:13 2018 +0300
IGNITE-10078 wip.
commit d212202a3911dc0c6a99dbb1d67e437b5109452d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 24 18:42:06 2018 +0300
IGNITE-10078 wip.
commit 987b344942483bd3e82f64f5bc47cba7f8cefb52
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 24 15:08:01 2018 +0300
IGNITE-10078 wip.
commit 79dd016d0ac88ae770150033035533d205aac62b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 24 14:53:19 2018 +0300
IGNITE-10078 wip.
commit dc110f0b8f56b72317b9446b4155529fc7dbf37d
Author: ascherbakoff <al...@gmail.com>
Date: Sun Dec 23 21:25:35 2018 +0300
IGNITE-10078 wip.
commit 39f7e740216e95f4253c0796fa087ee69796748d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 21 20:50:42 2018 +0300
IGNITE-10078 wip.
commit 2b668f0d20828c729c5a3536da806d4c43758792
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 21 20:49:19 2018 +0300
IGNITE-10078 wip.
commit ef0da6871a45e313d63ed7c364ea0f21b071b72e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 21 20:48:53 2018 +0300
IGNITE-10078 wip.
commit f213e4ed5d78202aeace9bb8629595709fa6874a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 21 19:11:01 2018 +0300
IGNITE-10078 wip.
commit aaa280fa7016fb7ca63ae55d80c3857e11f09229
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 19 20:03:30 2018 +0300
IGNITE-10078 wip.
commit 2ce83a2dcc9cde0428211f85d7eaa7eac5329368
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 19 14:30:35 2018 +0300
IGNITE-10078 wip.
commit e1a19d5d830513a007266908bd24859cd0e79d9c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 18:53:57 2018 +0300
IGNITE-10078 wip.
commit 56c48d55c555579abc28df3257d42a36806dbe80
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 18:38:22 2018 +0300
IGNITE-10078 wip.
commit 8c58d38f3179645b7dc5e00f72212be5f32d3bfb
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 17:56:27 2018 +0300
IGNITE-10078 wip.
commit 8e19369343c50cc49826ee909d4a5bdff6de67a9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 17:06:03 2018 +0300
IGNITE-10078 wip.
commit 9d708ca48cdff7da4a4e04e3ef80807ae3d3005f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 14:34:38 2018 +0300
IGNITE-10078 wip.
commit f3072e0288036c0543dade5909810f0600f669e2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 14:14:52 2018 +0300
IGNITE-10078 Enable one-phase commit.
commit c4b9664a3e6b6ab8229c1c714c16fb8c527e3eb0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 18 14:12:08 2018 +0300
IGNITE-10078 wip.
commit 161ebfa94f91469b1d945f75478661d3defc7831
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 17 19:54:15 2018 +0300
IGNITE-10078 wip.
commit 737b0b31ffff42fd8e33a85ce7b1098f66eae57f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 17 19:43:02 2018 +0300
IGNITE-10078 wip.
commit a7078dffdce93ce40411aa334cdb4c6282b168a4
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 17 18:02:09 2018 +0300
IGNITE-10078 wip.
commit 3f9f79bb7460bbc56f5c6a428d4302e814060f25
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 17 13:43:38 2018 +0300
IGNITE-10078 wip.
commit bdd8eb4ff0358a6359480449536ab6e18dd9d770
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 17 13:35:01 2018 +0300
IGNITE-10078 wip.
commit 2916f2a33772fa9d6bf3cd24b8bab26848b7bfb5
Author: ascherbakoff <al...@gmail.com>
Date: Sun Dec 16 16:17:50 2018 +0300
IGNITE-10078 wip.
commit d3845bce883c741eea9058518e4cef5e6d0e64d9
Author: ascherbakoff <al...@gmail.com>
Date: Sun Dec 16 15:20:24 2018 +0300
IGNITE-10078 wip.
commit e7258b457f1b571b60bee063790cfbd2bb0d66c1
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 19:56:22 2018 +0300
IGNITE-10078 wip.
commit 1fde3b63ea500b10d5aaf2ba7fc2faa047afb034
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 14:49:35 2018 +0300
IGNITE-10078 wip.
commit f46ae88f3326b2f832e76b4e47a3fa2ad302b275
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 14:36:10 2018 +0300
IGNITE-10078 wip.
commit 61b0c6d1c34a55b8e3c8d38ad6b2e33292809937
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 14:22:39 2018 +0300
IGNITE-10078 wip.
commit 2debfa927c8f8b96dc8e31b19e7be1b131b26c5c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 13:41:06 2018 +0300
IGNITE-10078 wip.
commit 909f2a349514ee42694b5b7a9cf1c559c16765b3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 13:11:57 2018 +0300
IGNITE-10078 wip.
commit 7877cb7ff8577ad5fac6361539fa56ef3c82c09b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 13:09:43 2018 +0300
IGNITE-10078 wip.
commit 143339e0d8a985dea90bfe730f1941f3741bfe4b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 14 12:52:10 2018 +0300
IGNITE-10078 wip.
commit 4280181b45cbb19aac66e2011786a299e6af5346
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 20:11:48 2018 +0300
IGNITE-10078 wip.
commit 823eef29dcd530e5afce3f39ec2f74be41ea7b08
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 19:39:32 2018 +0300
IGNITE-10078 wip.
commit 2a3ee55e26b2b556827bc32d4854c104343d2766
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 19:18:39 2018 +0300
IGNITE-10078 wip.
commit 2976329006cd1d8b7cf5b2d6ae2ab9fe96a0e217
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 18:25:10 2018 +0300
IGNITE-10078 wip.
commit fb92f91ece0e9749b4613a413022b4c447a49e89
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 18:11:13 2018 +0300
IGNITE-10078 wip.
commit c02c54bfe64bf5daa33a31576b95a09128400e44
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 18:04:13 2018 +0300
IGNITE-10078 wip.
commit 0ffdba5b270e2fa9c4a1aab475e13223868f2a7c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 16:28:54 2018 +0300
IGNITE-10078 wip.
commit 9b9cb50a2e6d650b34a7df82cfc80837badbaae3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 16:24:02 2018 +0300
IGNITE-10078 wip.
commit 546275e360c200baf1987f06b5724abc67de8c33
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 16:15:17 2018 +0300
IGNITE-10078 wip.
commit 9cf1280d47202a71e155fc400f5e09fc59313020
Merge: 96aabe9b7b 2bf085e877
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 14:14:03 2018 +0300
IGNITE-10078 wip.
commit 96aabe9b7bdd6b04198ec958538b94085aa5739b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 13:54:59 2018 +0300
IGNITE-10078 wip.
commit d3bbeddf6eeb02346c301dfa230795e7341de28a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 13 12:55:52 2018 +0300
IGNITE-10078 wip.
commit bf7337235b8aedf05b195ecf1b39486b407eb426
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 20:22:12 2018 +0300
IGNITE-10078 wip.
commit e624147bbe21b026079a2c4da22de06be0afd226
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 20:09:40 2018 +0300
IGNITE-10078 wip.
commit 261ddd48dc4f408443f56b52df84d075765dc615
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 20:01:42 2018 +0300
IGNITE-10078 wip.
commit 4e3c20e9012e83b34414ae9c3222347ba20febc7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 19:57:09 2018 +0300
IGNITE-10078 wip.
commit 17ae851b34c800c3986ce697da30bdc070206daf
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 19:27:44 2018 +0300
IGNITE-10078 wip.
commit 7016b30f0c42e369d713f18b4bffa101ac09626e
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 19:22:25 2018 +0300
IGNITE-10078 wip.
commit c53346f53f0bc5d8fabbb9e831eaa38725a85e62
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 18:51:16 2018 +0300
IGNITE-10078 wip.
commit 6ed9fba3d42113046a9520ce4b910d645734a3f7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 18:41:10 2018 +0300
IGNITE-10078 wip.
commit 98ce00d16c4e73414a51a4ca9486d0e37969b556
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 14:52:17 2018 +0300
IGNITE-10078 wip.
commit fe9719f7e16d35ffcfd448d2622c39e46bd01503
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 14:49:00 2018 +0300
IGNITE-10078 wip.
commit db071ae2add8d687b1604aec42f1e683fc7608bc
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 14:16:26 2018 +0300
IGNITE-10078 wip.
commit 2206b0d117c9628a6e13c2785a9cc8cd4f44bcb3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 12 14:06:28 2018 +0300
IGNITE-10078 wip.
commit 67dd96faf96048b1f50bf529fc268f1115e09c68
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 11 19:27:33 2018 +0300
IGNITE-10078 wip.
commit 3951f0baefab993882e2c8d8a1f916a23d89af85
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 11 19:24:45 2018 +0300
IGNITE-10078 wip.
commit 8948804cebb8ff409ef4d700f0d52d589cb4bf16
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 11 18:53:41 2018 +0300
IGNITE-10078 wip.
commit 4d182aa68b3b424390b04d7a1b8bcea79cd0070c
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 11 18:50:35 2018 +0300
IGNITE-10078 wip.
commit beb453b7b22aec136b6d79a0acd3cc7c7899d451
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 18:40:42 2018 +0300
IGNITE-10078 wip.
commit dd05b00f0afbe0a2121091c8e20d10222c6b6f0a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 18:34:03 2018 +0300
IGNITE-10078 wip.
commit 8d3842da5e130a361e52ace7b913933e6eb0d383
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 18:29:14 2018 +0300
IGNITE-10078 wip.
commit 0b904406859e2851ec484022044255d32804e3bd
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 18:25:15 2018 +0300
IGNITE-10078 wip.
commit 7e3df8f06124745c8aedd9f5c32535c98840a1bb
Merge: 1fc29dc2e0 87510597f5
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 18:20:33 2018 +0300
IGNITE-10078 wip.
commit 1fc29dc2e0514aa20fd08dcf60536eded391faea
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 17:06:42 2018 +0300
IGNITE-10078 wip.
commit a84bd13a5aaeb203d84ef31f14fc967708c697f6
Merge: 26cbfe770b 4c48ae0ad2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 17:04:25 2018 +0300
IGNITE-10078 wip.
commit 26cbfe770b37bf7d0f946868cc191b37baf94ef8
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 10 16:51:43 2018 +0300
IGNITE-10078 wip.
commit ada58ba6f146b6d556197fd658287173dc197629
Author: ascherbakoff <al...@gmail.com>
Date: Sun Dec 9 21:25:26 2018 +0300
IGNITE-10078 wip.
commit abb77c3d8167f6e3cbf5890cec8df9d930d802e1
Author: ascherbakoff <al...@gmail.com>
Date: Sun Dec 9 20:22:31 2018 +0300
IGNITE-10078 wip.
commit baab06840ac6ffeaf322be7ef0bedca6e6f90671
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Dec 7 20:05:45 2018 +0300
IGNITE-10078 wip.
commit 5ce148b0faa5415798a486b4d13fba8003d1623a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 6 18:47:35 2018 +0300
IGNITE-10078 wip.
commit aec4bf2336338bc995993045e3bca194606980ee
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 6 18:46:58 2018 +0300
IGNITE-10078 wip.
commit d3827452dcd0ca23b35b71f619e9beb854943618
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 6 16:45:12 2018 +0300
IGNITE-10078 wip.
commit ae248aae731c429d49b303a7c8dc3adf2cd53943
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 6 15:28:37 2018 +0300
IGNITE-10078 wip.
commit 272e08e602a0b04d966c1800efc142f44d615797
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 6 14:27:21 2018 +0300
IGNITE-10078 wip.
commit 3e747c8d12af9fed9851050c2dfa6d08439d68c0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Dec 6 13:44:13 2018 +0300
IGNITE-10078 wip.
commit a0e6a1d329911d40f68c1cd4b93f9d586878dab0
Author: ascherbakoff <al...@gmail.com>
Date: Wed Dec 5 23:25:06 2018 +0300
IGNITE-10078 wip.
commit 0a0328ee8c4faa2af1d0c31913b12a02d1d3fef5
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 5 20:10:54 2018 +0300
IGNITE-10078 wip.
commit 424855918b0f3c634b410fe4b90af0b3235a627a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 5 20:10:11 2018 +0300
IGNITE-10078 wip.
commit 39770b9ff5b273e80084306f5173f7496e9c29b0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Dec 5 19:09:15 2018 +0300
IGNITE-10078 wip.
commit 8cadd0666822420b1601f0acda3bf072296824a9
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 4 20:21:38 2018 +0300
IGNITE-10078 wip.
commit 5446ac7ef00b9521da9c586d72fd3a42d6a722b7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Dec 4 20:10:41 2018 +0300
IGNITE-10078 wip.
commit f45b1a5cefe332d538a1c505b9d1840d359da8a2
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 3 19:58:33 2018 +0300
IGNITE-10078 wip.
commit 191cf44411a230099bbe0ff97c589d3a617bae18
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 3 19:55:52 2018 +0300
IGNITE-10078 wip.
commit 68598271b519dc409680f86d5e303eaa24b91b3f
Merge: 0448651174 826cc5573f
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Dec 3 10:59:15 2018 +0300
Merge branch 'ignite-10078' of https://github.com/gridgain/apache-ignite into ignite-10078
commit 826cc5573f42daefa4914beba9d37df6d5e8faf8
Author: ascherbakoff <al...@gmail.com>
Date: Sun Dec 2 22:13:19 2018 +0300
IGNITE-10078 wip.
commit 603930c315e3b1999de0313e8ad2a4114bfa8cbe
Merge: 7a42fdbd82 2a0e354260
Author: ascherbakoff <al...@gmail.com>
Date: Fri Nov 30 12:05:35 2018 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit 0448651174c41d33a10df44add94c25cd62d6b2d
Merge: 7a42fdbd82 0e34042816
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Nov 28 16:52:10 2018 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit 7a42fdbd821c2e57c3edff16cca719e17505b68d
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Nov 22 13:21:36 2018 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionUpdateCounter.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
commit e9d52f94e9cb76f620bd9700aa1e7925f0a95842
Merge: a666157dc4 d81acdc29a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Nov 22 13:14:10 2018 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
# Conflicts:
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionUpdateCounter.java
# modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
commit a666157dc488c96fb5758daee24101c579e57b19
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Nov 21 19:10:03 2018 +0300
IGNITE-10078 wip.
commit 06aba801780def39cb00c23a3467a534f44b0b84
Author: ascherbakoff <al...@gmail.com>
Date: Wed Nov 21 01:31:03 2018 +0300
IGNITE-10078 wip.
commit 0b28c3d6da4285724116213d0b433160f62324cd
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Nov 19 17:05:32 2018 +0300
IGNITE-10078 wip.
commit 29eee5c2c2790ff474957760973dd617a0584a61
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Nov 19 17:02:32 2018 +0300
IGNITE-10078 wip.
commit aacff35491a07f93ea844e360f774a0708b155c8
Merge: 97aba597a9 355ce6fe88
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Nov 19 16:55:38 2018 +0300
IGNITE-10078 wip.
commit 97aba597a95ea4dc5e2684dfb7bc68c23e3a98d0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Nov 19 16:49:39 2018 +0300
IGNITE-10078 wip.
commit 30a8f30eef9d76d5aa72f2bc43882c7e47f5d221
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Nov 19 16:20:16 2018 +0300
IGNITE-10078 wip.
commit d176c8b30c303f19b5beeff640e7ed5b961f81c3
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Mon Nov 19 13:34:39 2018 +0300
IGNITE-10078 wip.
commit 22436a83dc0993461c08155b9e68b612dda3360a
Author: ascherbakoff <al...@gmail.com>
Date: Sun Nov 18 18:37:16 2018 +0300
IGNITE-10078 wip.
commit ef7a7857fc00bebe9fc9289ecdb687c43973e947
Author: ascherbakoff <al...@gmail.com>
Date: Sun Nov 18 17:43:15 2018 +0300
IGNITE-10078 wip.
commit e721aba13512433caf9b6420e00dfef76dce3c47
Author: ascherbakoff <al...@gmail.com>
Date: Sun Nov 18 17:31:20 2018 +0300
IGNITE-10078 wip.
commit 2efba0a10b64490ac435e0157a5eeca8c2712ecc
Author: ascherbakoff <al...@gmail.com>
Date: Sun Nov 18 17:12:14 2018 +0300
IGNITE-10078 wip.
commit e210e1cb26e774625252b1a2f11d295f80f48351
Author: ascherbakoff <al...@gmail.com>
Date: Sun Nov 18 17:06:45 2018 +0300
IGNITE-10078 wip.
commit 63d7ab771d664eafc1e5f18f7a2f51500113316b
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Fri Nov 16 18:51:59 2018 +0300
IGNITE-10078 wip.
commit 2317758268879c647d80367f44c121645713de78
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Nov 14 17:45:49 2018 +0300
IGNITE-10078 wip.
commit 64d7e2d2a235fb822b68ca21f02d85f43f88b019
Merge: defbcc167a 2439ade4d6
Author: ascherbakoff <al...@gmail.com>
Date: Mon Nov 12 22:42:43 2018 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit defbcc167aaf358991c2874b2b0d600b6248f921
Author: ascherbakoff <al...@gmail.com>
Date: Mon Nov 12 22:41:57 2018 +0300
IGNITE-10078 wip.
commit a43e5876cb81bb00fdbccc004d28e9c4ceda475a
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Tue Nov 6 10:31:38 2018 +0300
IGNITE-10078 wip.
commit beb579c83782ef4d2be91a29c43b99410e4f8d6d
Merge: 253df1059b 6f9c702cd7
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Thu Nov 1 12:51:24 2018 +0300
Merge branch 'master' of https://github.com/apache/ignite into ignite-10078
commit 253df1059b0ad0f003a711e63007df7b2e1b77c0
Author: Aleksei Scherbakov <al...@gmail.com>
Date: Wed Oct 31 18:38:07 2018 +0300
IGNITE-10078 wip.
Signed-off-by: Anton Vinogradov <av...@apache.org>
---
.../org/apache/ignite/IgniteSystemProperties.java | 7 +
.../src/main/java/org/apache/ignite/Ignition.java | 2 +-
.../apache/ignite/internal/pagemem/FullPageId.java | 6 +-
.../pagemem/wal/record/RollbackRecord.java | 115 +++
.../internal/pagemem/wal/record/WALRecord.java | 8 +-
.../delta/MetaPageUpdatePartitionDataRecord.java | 38 +-
.../delta/MetaPageUpdatePartitionDataRecordV2.java | 103 ++
.../wal/record/delta/PartitionMetaStateRecord.java | 8 +-
.../processors/affinity/AffinityAssignment.java | 2 +-
.../affinity/GridAffinityAssignmentCache.java | 14 +-
.../cache/CacheAffinitySharedManager.java | 334 ++----
.../processors/cache/CacheEntryInfoCollection.java | 19 +
.../processors/cache/CacheGroupContext.java | 13 +
.../processors/cache/GridCacheMapEntry.java | 51 +-
.../cache/GridCachePartitionExchangeManager.java | 10 +-
.../processors/cache/GridCacheProcessor.java | 32 +-
.../cache/GridCacheSharedTtlCleanupManager.java | 9 +-
.../internal/processors/cache/GridCacheUtils.java | 3 +-
.../cache/IgniteCacheOffheapManager.java | 61 +-
.../cache/IgniteCacheOffheapManagerImpl.java | 94 +-
.../cache/PartitionAtomicUpdateCounterImpl.java | 155 +++
....java => PartitionMvccTxUpdateCounterImpl.java} | 41 +-
.../PartitionTxUpdateCounterDebugWrapper.java | 201 ++++
.../cache/PartitionTxUpdateCounterImpl.java | 450 ++++++++
.../processors/cache/PartitionUpdateCounter.java | 223 ++--
.../internal/processors/cache/WalStateManager.java | 10 +-
.../GridDistributedTxRemoteAdapter.java | 3 +-
.../cache/distributed/dht/GridDhtCacheEntry.java | 28 +-
.../distributed/dht/GridDhtTxFinishFuture.java | 9 +-
.../distributed/dht/GridDhtTxFinishRequest.java | 7 -
.../distributed/dht/GridDhtTxPrepareFuture.java | 35 +-
.../dht/PartitionUpdateCountersMessage.java | 24 +
.../dht/preloader/GridDhtPartitionDemander.java | 6 +-
.../dht/preloader/GridDhtPartitionSupplier.java | 9 +
.../preloader/GridDhtPartitionsExchangeFuture.java | 75 +-
.../dht/preloader/GridDhtPreloader.java | 8 +-
.../dht/preloader/GridDhtPreloaderAssignments.java | 3 +-
.../preloader/IgniteDhtDemandedPartitionsMap.java | 3 +
.../dht/topology/GridClientPartitionTopology.java | 7 +-
.../dht/topology/GridDhtLocalPartition.java | 121 ++-
.../dht/topology/GridDhtPartitionTopology.java | 12 +-
.../dht/topology/GridDhtPartitionTopologyImpl.java | 120 ++-
.../dht/topology/PartitionsEvictManager.java | 52 +-
.../GridNearOptimisticTxPrepareFutureAdapter.java | 6 +-
.../cache/distributed/near/GridNearTxLocal.java | 15 +-
.../processors/cache/persistence/CacheDataRow.java | 8 +
.../cache/persistence/CacheDataRowAdapter.java | 2 +-
.../GridCacheDatabaseSharedManager.java | 78 +-
.../cache/persistence/GridCacheOffheapManager.java | 365 +++++--
.../processors/cache/persistence/RowStore.java | 6 +
.../processors/cache/persistence/Storable.java | 7 +
.../persistence/checkpoint/CheckpointEntry.java | 3 +-
.../persistence/freelist/AbstractFreeList.java | 37 +-
.../persistence/freelist/CacheFreeListImpl.java | 10 +-
.../cache/persistence/freelist/PagesList.java | 14 +-
.../SimpleDataRow.java} | 82 +-
.../cache/persistence/metastorage/MetaStorage.java | 133 +--
.../metastorage/MetastorageDataRow.java | 64 +-
.../metastorage/MetastorageRowStore.java | 32 +-
.../MetastoreDataPageIO.java} | 39 +-
.../PartitionMetaStorage.java} | 33 +-
.../partstorage/PartitionMetaStorageImpl.java | 140 +++
.../cache/persistence/tree/BPlusTree.java | 1 +
.../persistence/tree/io/AbstractDataPageIO.java | 1 -
.../cache/persistence/tree/io/PageIO.java | 7 +
.../persistence/tree/io/PagePartitionMetaIO.java | 34 +
.../persistence/tree/io/PagePartitionMetaIOV2.java | 51 +-
.../persistence/tree/io/SimpleDataPageIO.java | 35 +-
.../cache/persistence/tree/util/PageHandler.java | 3 +-
.../persistence/wal/FileWriteAheadLogManager.java | 19 +-
.../cache/persistence/wal/record/RecordTypes.java | 1 +
.../wal/serializer/RecordDataV1Serializer.java | 37 +-
.../wal/serializer/RecordDataV2Serializer.java | 22 +
.../CacheContinuousQueryEventBuffer.java | 14 +-
.../continuous/CacheContinuousQueryHandler.java | 6 +-
.../cache/transactions/IgniteTxEntry.java | 19 +
.../cache/transactions/IgniteTxHandler.java | 88 +-
.../cache/transactions/IgniteTxLocalAdapter.java | 34 +-
.../cache/transactions/IgniteTxManager.java | 4 +-
.../processors/cache/transactions/TxCounters.java | 25 +-
.../cluster/GridClusterStateProcessor.java | 3 +-
.../ignite/internal/stat/IoStatisticsHolder.java | 1 -
.../apache/ignite/internal/util/IgniteTree.java | 5 +-
.../apache/ignite/internal/util/IgniteUtils.java | 62 +-
modules/core/src/test/config/log4j-test.xml | 9 +
.../ignite/cache/ResetLostPartitionTest.java | 5 +-
.../internal/TestRecordingCommunicationSpi.java | 55 +-
.../processors/cache/IgniteCacheGroupsTest.java | 16 +-
.../CachePartitionLossDetectionOnNodeLeftTest.java | 115 +++
.../distributed/CacheRentingStateRepairTest.java | 25 +-
.../GridCacheRebalancingWithAsyncClearingTest.java | 12 +-
.../IgnitePdsCacheRebalancingAbstractTest.java | 4 +
.../IgnitePdsContinuousRestartTest.java | 10 +
...tePdsContinuousRestartTestWithExpiryPolicy.java | 1 +
.../persistence/IgnitePdsCorruptedStoreTest.java | 40 +-
.../db/IgnitePdsPartitionPreloadTest.java | 19 +-
.../persistence/db/wal/IgniteWalRebalanceTest.java | 2 +-
.../db/wal/IgniteWalSerializerVersionTest.java | 2 +-
.../db/wal/WalRecoveryTxLogicalRecordsTest.java | 162 ++-
.../transactions/PartitionUpdateCounterTest.java | 425 ++++++++
.../TxLocalDhtMixedCacheModesTest.java | 86 ++
.../TxPartitionCounterStateAbstractTest.java | 1081 ++++++++++++++++++++
...ounterStateConsistencyHistoryRebalanceTest.java | 191 ++++
.../TxPartitionCounterStateConsistencyTest.java | 490 +++++++++
...ateOnePrimaryOneBackupHistoryRebalanceTest.java | 41 +
...rtitionCounterStateOnePrimaryOneBackupTest.java | 491 +++++++++
...imaryTwoBackupsFailAllHistoryRebalanceTest.java | 100 ++
...ounterStateOnePrimaryTwoBackupsFailAllTest.java | 352 +++++++
...teOnePrimaryTwoBackupsHistoryRebalanceTest.java | 64 ++
...titionCounterStateOnePrimaryTwoBackupsTest.java | 913 +++++++++++++++++
.../TxPartitionCounterStatePutTest.java | 289 ++++++
...titionCounterStateTwoPrimaryTwoBackupsTest.java | 225 ++++
.../TxPartitionCounterStateWithFilterTest.java | 200 ++++
.../cache/transactions/TxRollbackAsyncTest.java | 2 +-
.../testframework/junits/GridAbstractTest.java | 3 +
.../ignite/testframework/junits/Repeat.java} | 51 +-
.../ignite/testframework/junits/RepeatRule.java | 67 ++
.../junits/common/GridCommonAbstractTest.java | 196 +++-
.../testsuites/IgniteCacheMvccTestSuite6.java | 4 +
.../testsuites/IgniteCacheMvccTestSuite9.java | 22 +
.../ignite/testsuites/IgniteCacheTestSuite6.java | 6 +
.../ignite/testsuites/IgniteCacheTestSuite9.java | 24 +
.../processors/cache/CacheIndexStreamerTest.java | 3 +
123 files changed, 8591 insertions(+), 1289 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 800ca56..a8916b8 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -1145,6 +1145,13 @@ public final class IgniteSystemProperties {
public static final String IGNITE_DIAGNOSTIC_WARN_LIMIT = "IGNITE_DIAGNOSTIC_WARN_LIMIT";
/**
+ * Flag to enable triggering failure handler for node if unrecoverable partition inconsistency is
+ * discovered during partition update counters exchange.
+ */
+ public static final String IGNITE_FAIL_NODE_ON_UNRECOVERABLE_PARTITION_INCONSISTENCY =
+ "IGNITE_FAIL_NODE_ON_UNRECOVERABLE_PARTITION_INCONSISTENCY";
+
+ /**
* Allow use composite _key, _val columns at the INSERT/UPDATE/MERGE statements.
*/
public static final String IGNITE_SQL_ALLOW_KEY_VAL_UPDATES = "IGNITE_SQL_ALLOW_KEY_VAL_UPDATES";
diff --git a/modules/core/src/main/java/org/apache/ignite/Ignition.java b/modules/core/src/main/java/org/apache/ignite/Ignition.java
index 4c7a491..dd0d796 100644
--- a/modules/core/src/main/java/org/apache/ignite/Ignition.java
+++ b/modules/core/src/main/java/org/apache/ignite/Ignition.java
@@ -583,4 +583,4 @@ public class Ignition {
return TcpIgniteClient.start(cfg);
}
-}
\ No newline at end of file
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java
index 9e24943..17c552d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/FullPageId.java
@@ -40,10 +40,10 @@ import org.apache.ignite.internal.util.typedef.internal.U;
* <p>
* <h3>Page ID rotation</h3>
* There are scenarios when we reference one page (B) from within another page (A) by page ID. It is also
- * possible that this first page (B) is de-allocated and allocated again for a different purpose. In this
- * case we should have a mechanism to determine that page (B) cannot be used after reading it's ID in page (A).
+ * possible that this first page (B) is concurrently reused for a different purpose. In this
+ * case we should have a mechanism to determine that the reference from page (A) to page (B) is no longer valid.
* This is ensured by page ID rotation - together with page's (B) ID we should write some value that is incremented
- * each time a page is de-allocated (page ID rotation). This ID should be verified after page read and a page
+ * each time a page is reused (page ID rotation). This ID should be verified after page read and a page
* should be discarded if full ID is different.
* <p>
* Effective page ID is page ID with zeroed bits used for page ID rotation.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/RollbackRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/RollbackRecord.java
new file mode 100644
index 0000000..fd6a00e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/RollbackRecord.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.pagemem.wal.record;
+
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Rollback record. Used to close gap in partition update sequence on tx rollback.
+ */
+public class RollbackRecord extends WALRecord {
+ /** Cache ID. */
+ @GridToStringInclude
+ protected int grpId;
+
+ /** Partition ID. */
+ @GridToStringInclude
+ protected int partId;
+
+ /** Rollback start. */
+ @GridToStringInclude
+ protected long start;
+
+ /** Rollback range. */
+ @GridToStringInclude
+ protected long range;
+
+ /**
+ * @param grpId Group id.
+ * @param partId Partition id.
+ * @param start Start.
+ * @param range Range.
+ */
+ public RollbackRecord(int grpId, int partId, long start, long range) {
+ this.grpId = grpId;
+ this.partId = partId;
+ this.start = start;
+ this.range = range;
+ }
+
+ /**
+ * @return Cache ID.
+ */
+ public int groupId() {
+ return grpId;
+ }
+
+ /**
+ * @return Partition ID.
+ */
+ public int partitionId() {
+ return partId;
+ }
+
+ /**
+ * @return Rollback start.
+ */
+ public long start() {
+ return start;
+ }
+
+ /**
+ * @return Rollback range.
+ */
+ public long range() {
+ return range;
+ }
+
+ /**
+ * Returns a number of overlapping update counters.
+ *
+ * @param from From counter (not inclusive).
+ * @param to To counter (inclusive).
+ */
+ public long overlap(long from, long to) {
+ long to0 = start + range;
+
+ // from lies within (start, to0]
+ if (start <= from && from < to0)
+ return Math.min(to0 - from, to - from);
+
+ // start lies within (from, to]
+ if (from <= start && start < to)
+ return Math.min(to - start, range);
+
+ return 0;
+ }
+
+
+
+ /** {@inheritDoc} */
+ @Override public RecordType type() {
+ return RecordType.ROLLBACK_TX_RECORD;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(RollbackRecord.class, this);
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
index 5d72768..9cf2613 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
@@ -208,7 +208,13 @@ public abstract class WALRecord {
MVCC_DATA_RECORD (LOGICAL),
/** Mvcc Tx state change record. */
- MVCC_TX_RECORD (LOGICAL);
+ MVCC_TX_RECORD (LOGICAL),
+
+ /** Rollback tx record. */
+ ROLLBACK_TX_RECORD (LOGICAL),
+
+ /** */
+ PARTITION_META_PAGE_UPDATE_COUNTERS_V2 (PHYSICAL);
/**
* When you're adding a new record don't forget to choose record purpose explicitly
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
index 28294a9..3e2b67b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
@@ -17,7 +17,11 @@
package org.apache.ignite.internal.pagemem.wal.record.delta;
+import java.io.DataInput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.PageIdUtils;
import org.apache.ignite.internal.pagemem.PageMemory;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PagePartitionMetaIO;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -57,8 +61,7 @@ public class MetaPageUpdatePartitionDataRecord extends PageDeltaRecord {
int partSize,
long cntrsPageId,
byte state,
- int allocatedIdxCandidate
- ) {
+ int allocatedIdxCandidate) {
super(grpId, pageId);
this.updateCntr = updateCntr;
@@ -70,6 +73,20 @@ public class MetaPageUpdatePartitionDataRecord extends PageDeltaRecord {
}
/**
+ * @param in Input.
+ */
+ public MetaPageUpdatePartitionDataRecord(DataInput in) throws IOException{
+ super(in.readInt(), in.readLong());
+
+ this.updateCntr = in.readLong();
+ this.globalRmvId = in.readLong();
+ this.partSize = in.readInt();
+ this.cntrsPageId = in.readLong();
+ this.state = in.readByte();
+ this.allocatedIdxCandidate = in.readInt();
+ }
+
+ /**
* @return Update counter.
*/
public long updateCounter() {
@@ -123,6 +140,21 @@ public class MetaPageUpdatePartitionDataRecord extends PageDeltaRecord {
return allocatedIdxCandidate;
}
+ /**
+ * @param buf Buffer.
+ */
+ public void toBytes(ByteBuffer buf) {
+ buf.putInt(groupId());
+ buf.putLong(pageId());
+
+ buf.putLong(updateCounter());
+ buf.putLong(globalRemoveId());
+ buf.putInt(partitionSize());
+ buf.putLong(countersPageId());
+ buf.put(state());
+ buf.putInt(allocatedIndexCandidate());
+ }
+
/** {@inheritDoc} */
@Override public RecordType type() {
return RecordType.PARTITION_META_PAGE_UPDATE_COUNTERS;
@@ -130,6 +162,6 @@ public class MetaPageUpdatePartitionDataRecord extends PageDeltaRecord {
/** {@inheritDoc} */
@Override public String toString() {
- return S.toString(MetaPageUpdatePartitionDataRecord.class, this, "super", super.toString());
+ return S.toString(MetaPageUpdatePartitionDataRecord.class, this, "partId", PageIdUtils.partId(pageId()), "super", super.toString());
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecordV2.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecordV2.java
new file mode 100644
index 0000000..ab3ccf8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecordV2.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.pagemem.wal.record.delta;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.PageIdUtils;
+import org.apache.ignite.internal.pagemem.PageMemory;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.PagePartitionMetaIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.PagePartitionMetaIOV2;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ *
+ */
+public class MetaPageUpdatePartitionDataRecordV2 extends MetaPageUpdatePartitionDataRecord {
+ /** */
+ private long link;
+
+ /**
+ * @param grpId Group id.
+ * @param pageId Page id.
+ * @param updateCntr Update counter.
+ * @param globalRmvId Global remove id.
+ * @param partSize Partition size.
+ * @param cntrsPageId Cntrs page id.
+ * @param state State.
+ * @param allocatedIdxCandidate Allocated index candidate.
+ * @param link Link.
+ */
+ public MetaPageUpdatePartitionDataRecordV2(
+ int grpId,
+ long pageId,
+ long updateCntr,
+ long globalRmvId,
+ int partSize,
+ long cntrsPageId,
+ byte state,
+ int allocatedIdxCandidate,
+ long link) {
+ super(grpId, pageId, updateCntr, globalRmvId, partSize, cntrsPageId, state, allocatedIdxCandidate);
+ this.link = link;
+ }
+
+ /**
+ * @param in Input.
+ */
+ public MetaPageUpdatePartitionDataRecordV2(DataInput in) throws IOException {
+ super(in);
+
+ this.link = in.readLong();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void applyDelta(PageMemory pageMem, long pageAddr) throws IgniteCheckedException {
+ super.applyDelta(pageMem, pageAddr);
+
+ PagePartitionMetaIOV2 io = (PagePartitionMetaIOV2)PagePartitionMetaIO.VERSIONS.forPage(pageAddr);
+
+ io.setGapsLink(pageAddr, link);
+ }
+
+ /**
+ *
+ */
+ public long link() {
+ return link;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void toBytes(ByteBuffer buf) {
+ super.toBytes(buf);
+
+ buf.putLong(link());
+ }
+
+ /** {@inheritDoc} */
+ @Override public RecordType type() {
+ return RecordType.PARTITION_META_PAGE_UPDATE_COUNTERS_V2;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(MetaPageUpdatePartitionDataRecordV2.class, this, "partId", PageIdUtils.partId(pageId()), "super", super.toString());
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
index e1e74c4..399ffc2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
@@ -35,12 +35,14 @@ public class PartitionMetaStateRecord extends WALRecord implements WalRecordCach
/** Partition id. */
private final int partId;
- /** Update counter. */
+ /** @deprecated Update counter. */
private final long updateCounter;
/**
* @param grpId Cache group ID.
- * @param state Page ID.
+ * @param partId Partition ID.
+ * @param state State.
+ * @param updateCounter Update counter.
*/
public PartitionMetaStateRecord(int grpId, int partId, GridDhtPartitionState state, long updateCounter) {
this.grpId = grpId;
@@ -74,7 +76,7 @@ public class PartitionMetaStateRecord extends WALRecord implements WalRecordCach
}
/**
- *
+ * @return Rollback counter.
*/
public long updateCounter() {
return updateCounter;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/AffinityAssignment.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/AffinityAssignment.java
index b8b1089..502672c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/AffinityAssignment.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/AffinityAssignment.java
@@ -74,7 +74,7 @@ public interface AffinityAssignment {
public Collection<UUID> getIds(int part);
/**
- * @return Nodes having parimary and backup assignments.
+ * @return Nodes having primary and backup assignments.
*/
public Set<ClusterNode> nodes();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
index 7c2b1dc..53664b8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
@@ -352,22 +352,22 @@ public class GridAffinityAssignmentCache {
if (hasBaseline && changedBaseline) {
recalculateBaselineAssignment(topVer, events, prevAssignment, sorted, blt);
- assignment = IdealAffinityAssignment.createWithPreservedPrimaries(
+ assignment = IdealAffinityAssignment.create(
topVer,
- baselineAssignmentWithoutOfflineNodes(topVer),
- baselineAssignment
+ sorted,
+ baselineAssignmentWithoutOfflineNodes(topVer)
);
}
else if (skipCalculation)
assignment = prevAssignment;
- else if (hasBaseline && !changedBaseline) {
+ else if (hasBaseline) {
if (baselineAssignment == null)
recalculateBaselineAssignment(topVer, events, prevAssignment, sorted, blt);
- assignment = IdealAffinityAssignment.createWithPreservedPrimaries(
+ assignment = IdealAffinityAssignment.create(
topVer,
- baselineAssignmentWithoutOfflineNodes(topVer),
- baselineAssignment
+ sorted,
+ baselineAssignmentWithoutOfflineNodes(topVer)
);
}
else {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
index 9a80d8a..7bdb602 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
@@ -269,7 +269,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
CacheAffinityChangeMessage msg = null;
synchronized (mux) {
- if (waitInfo == null || !waitInfo.topVer.equals(lastAffVer) )
+ if (waitInfo == null || !waitInfo.topVer.equals(lastAffVer))
return;
Map<Integer, UUID> partWait = waitInfo.waitGrps.get(checkGrpId);
@@ -324,7 +324,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
*/
public Set<Integer> waitGroups() {
synchronized (mux) {
- if (waitInfo == null || !waitInfo.topVer.equals(lastAffVer) )
+ if (waitInfo == null || !waitInfo.topVer.equals(lastAffVer))
return Collections.emptySet();
return new HashSet<>(waitInfo.waitGrps.keySet());
@@ -332,6 +332,21 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
}
/**
+ * @param grpId Group id.
+ * @param part Part.
+ * @param node Node.
+ * @param topVer Topology version.
+ */
+ public void addToWaitGroup(int grpId, int part, UUID node, AffinityTopologyVersion topVer) {
+ synchronized (mux) {
+ if (waitInfo == null)
+ waitInfo = new WaitRebalanceInfo(topVer);
+
+ waitInfo.add(grpId, part, node, null);
+ }
+ }
+
+ /**
* @param waitInfo Cache rebalance information.
* @return Message.
*/
@@ -495,6 +510,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
clientTop.fullUpdateCounters(),
Collections.<Integer>emptySet(),
null,
+ null,
null
);
}
@@ -560,7 +576,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
-1,
false);
- grp.topology().update(topVer, partMap, null, Collections.emptySet(), null, null);
+ grp.topology().update(topVer, partMap, null, Collections.emptySet(), null, null, null);
topFut.validate(grp, discoCache.allNodes());
}
@@ -791,8 +807,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
}
/**
- * Called during the rollback of the exchange partitions procedure
- * in order to stop the given cache even if it's not fully initialized (e.g. failed on cache init stage).
+ * Called during the rollback of the exchange partitions procedure in order to stop the given cache even if it's not
+ * fully initialized (e.g. failed on cache init stage).
*
* @param fut Exchange future.
* @param crd Coordinator flag.
@@ -803,7 +819,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
boolean crd,
final ExchangeActions exchActions
) {
- assert exchActions != null && !exchActions.empty() && exchActions.cacheStartRequests().isEmpty(): exchActions;
+ assert exchActions != null && !exchActions.empty() && exchActions.cacheStartRequests().isEmpty() : exchActions;
IgniteInternalFuture<?> res = cachesRegistry.update(exchActions);
@@ -1613,182 +1629,15 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
* @throws IgniteCheckedException If failed.
*/
public Map<Integer, CacheGroupAffinityMessage> onServerLeftWithExchangeMergeProtocol(
- final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException
- {
- final ExchangeDiscoveryEvents evts = fut.context().events();
-
- assert fut.context().mergeExchanges();
- assert evts.hasServerLeft();
-
- if (evts.hasServerLeft() && evts.hasServerJoin())
- return onReassignmentEnforced(fut);
- else
- return onServerLeftWithExchangeMergeProtocolLightweight(fut);
- }
-
- /**
- * @param fut Current exchange future.
- * @return Computed difference with ideal affinity.
- * @throws IgniteCheckedException If failed.
- */
- private Map<Integer, CacheGroupAffinityMessage> onServerLeftWithExchangeMergeProtocolLightweight(
- final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException
- {
+ final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException {
final ExchangeDiscoveryEvents evts = fut.context().events();
- final AffinityTopologyVersion topVer = evts.topologyVersion();
assert fut.context().mergeExchanges();
assert evts.hasServerLeft();
- final WaitRebalanceInfo waitRebalanceInfo =
- new WaitRebalanceInfo(fut.context().events().lastServerEventVersion());
-
- final Map<Integer, Map<Integer, List<Long>>> diff = new ConcurrentHashMap<>();
-
- final Set<ClusterNode> aliveNodes = new HashSet<>(fut.context().events().discoveryCache().serverNodes());
-
- forAllRegisteredCacheGroups(new IgniteInClosureX<CacheGroupDescriptor>() {
- @Override public void applyx(CacheGroupDescriptor desc) throws IgniteCheckedException {
- AffinityTopologyVersion topVer = evts.topologyVersion();
-
- CacheGroupHolder grpHolder = getOrCreateGroupHolder(topVer, desc);
-
- IdealAffinityAssignment idealAssignment = grpHolder.affinity().calculate(topVer, evts, evts.discoveryCache());
-
- if (!grpHolder.rebalanceEnabled || fut.cacheGroupAddedOnExchange(desc.groupId(), desc.receivedFrom())) {
- grpHolder.affinity().initialize(topVer, idealAssignment.assignment());
-
- return;
- }
-
- AffinityTopologyVersion affTopVer = grpHolder.affinity().lastVersion();
-
- List<List<ClusterNode>> curAssignment = grpHolder.affinity().assignments(affTopVer);
-
- assert curAssignment != null;
-
- List<List<ClusterNode>> newAssignment = new ArrayList<>(idealAssignment.assignment());
-
- GridDhtPartitionTopology top = grpHolder.topology(fut.context().events().discoveryCache());
-
- BitSet processedPartitions = new BitSet(curAssignment.size());
-
- Map<Integer, List<Long>> cacheAffinityDiff = new HashMap<>();
-
- for (ClusterNode leftNode : evts.leftServerNodes()) {
- for (int p : idealAssignment.idealPrimaries(leftNode)) {
- List<ClusterNode> curOwners = curAssignment.get(p);
-
- if (curOwners.isEmpty())
- continue;
-
- List<ClusterNode> idealOwners = idealAssignment.assignment().get(p);
-
- List<ClusterNode> newOwners = null;
-
- if (idealOwners.isEmpty())
- newOwners = selectCurrentAliveOwners(aliveNodes, curOwners);
- else if (curOwners.get(0).equals(leftNode))
- newOwners = selectPrimaryTopologyOwnerFromIdealAssignment(
- grpHolder.aff,
- p,
- top,
- idealOwners,
- waitRebalanceInfo
- );
- else if (!curOwners.get(0).equals(idealOwners.get(0)))
- newOwners = latePrimaryAssignment(
- grpHolder.aff,
- p,
- curOwners.get(0),
- idealOwners,
- waitRebalanceInfo
- );
-
- if (newOwners != null) {
- newAssignment.set(p, newOwners);
-
- List<Long> clusterNodesAsOrder = newOwners.stream()
- .map(NODE_TO_ORDER::apply)
- .collect(Collectors.toList());
-
- cacheAffinityDiff.put(p, clusterNodesAsOrder);
-
- processedPartitions.set(p);
- }
- }
- }
-
- Set<Integer> partitionsWithChangedPrimary = grpHolder.affinity().partitionPrimariesDifferentToIdeal(affTopVer);
-
- // We need to re-check partitions for further correct late affinity assignment
- // where primary node is not as in ideal assignment.
- for (int p : partitionsWithChangedPrimary) {
- if (processedPartitions.get(p))
- continue;
-
- List<ClusterNode> curOwners = curAssignment.get(p);
-
- if (curOwners.isEmpty())
- continue;
-
- List<ClusterNode> idealOwners = idealAssignment.assignment().get(p);
-
- List<ClusterNode> newOwners = null;
-
- if (idealOwners.isEmpty())
- newOwners = selectCurrentAliveOwners(aliveNodes, curOwners);
- else if (!aliveNodes.contains(curOwners.get(0)))
- newOwners = selectPrimaryTopologyOwnerFromIdealAssignment(
- grpHolder.aff,
- p,
- top,
- idealOwners,
- waitRebalanceInfo
- );
- else if (!curOwners.get(0).equals(idealOwners.get(0)))
- // Current distribution was already not ideal. Preserve it for late affinity assignment.
- newOwners = latePrimaryAssignment(
- grpHolder.aff,
- p,
- curOwners.get(0),
- idealOwners,
- waitRebalanceInfo
- );
-
- if (newOwners != null) {
- newAssignment.set(p, newOwners);
-
- List<Long> clusterNodesAsOrder = newOwners.stream()
- .map(NODE_TO_ORDER::apply)
- .collect(Collectors.toList());
-
- cacheAffinityDiff.put(p, clusterNodesAsOrder);
- }
- }
-
- if (!cacheAffinityDiff.isEmpty())
- diff.put(grpHolder.groupId(), cacheAffinityDiff);
-
- grpHolder.affinity().initialize(topVer, newAssignment);
-
- fut.timeBag().finishLocalStage("Affinity initialization (on server left) " +
- "[grp=" + desc.cacheOrGroupName() + "]");
- }
- });
-
- synchronized (mux) {
- this.waitInfo = !waitRebalanceInfo.empty() ? waitRebalanceInfo : null;
-
- WaitRebalanceInfo info = this.waitInfo;
-
- if (log.isDebugEnabled()) {
- log.debug("Computed new affinity after node left [topVer=" + topVer +
- ", waitGrps=" + (info != null ? groupNames(info.waitGrps.keySet()) : null) + ']');
- }
- }
+ Map<Integer, CacheGroupAffinityMessage> result = onReassignmentEnforced(fut);
- return CacheGroupAffinityMessage.createAffinityDiffMessages(diff);
+ return result;
}
/**
@@ -1862,8 +1711,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
* @throws IgniteCheckedException If failed.
*/
public Map<Integer, CacheGroupAffinityMessage> onCustomEventWithEnforcedAffinityReassignment(
- final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException
- {
+ final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException {
assert DiscoveryCustomEvent.requiresCentralizedAffinityAssignment(fut.firstEvent());
Map<Integer, CacheGroupAffinityMessage> result = onReassignmentEnforced(fut);
@@ -1879,8 +1727,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
* @throws IgniteCheckedException If failed.
*/
private Map<Integer, CacheGroupAffinityMessage> onReassignmentEnforced(
- final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException
- {
+ final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException {
final ExchangeDiscoveryEvents evts = fut.context().events();
forAllRegisteredCacheGroups(new IgniteInClosureX<CacheGroupDescriptor>() {
@@ -1966,7 +1813,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
* @param crd Coordinator flag.
* @throws IgniteCheckedException If failed.
*/
- public void onBaselineTopologyChanged(final GridDhtPartitionsExchangeFuture fut, boolean crd) throws IgniteCheckedException {
+ public void onBaselineTopologyChanged(final GridDhtPartitionsExchangeFuture fut,
+ boolean crd) throws IgniteCheckedException {
assert !fut.firstEvent().eventNode().isClient();
WaitRebalanceInfo waitRebalanceInfo = initAffinityOnNodeJoin(fut, crd);
@@ -2094,8 +1942,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
* @param discoCache Discovery data cache.
* @param affCache Affinity.
* @param fetchFut Affinity fetch future.
- * @throws IgniteCheckedException If failed.
* @return Affinity assignment response.
+ * @throws IgniteCheckedException If failed.
*/
private GridDhtAffinityAssignmentResponse fetchAffinity(
AffinityTopologyVersion topVer,
@@ -2139,10 +1987,11 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
*
* @param fut Exchange future.
* @param crd Coordinator flag.
- * @throws IgniteCheckedException If failed.
* @return {@code True} if affinity should be assigned by coordinator.
+ * @throws IgniteCheckedException If failed.
*/
- public boolean onCentralizedAffinityChange(final GridDhtPartitionsExchangeFuture fut, boolean crd) throws IgniteCheckedException {
+ public boolean onCentralizedAffinityChange(final GridDhtPartitionsExchangeFuture fut,
+ boolean crd) throws IgniteCheckedException {
assert (fut.events().hasServerLeft() && !fut.firstEvent().eventNode().isClient()) ||
DiscoveryCustomEvent.requiresCentralizedAffinityAssignment(fut.firstEvent()) : fut.firstEvent();
@@ -2169,8 +2018,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
/**
* @param fut Exchange future.
* @param newAff {@code True} if there are no older nodes with affinity info available.
- * @throws IgniteCheckedException If failed.
* @return Future completed when caches initialization is done.
+ * @throws IgniteCheckedException If failed.
*/
public IgniteInternalFuture<?> initCoordinatorCaches(
final GridDhtPartitionsExchangeFuture fut,
@@ -2241,10 +2090,10 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
}
GridDhtAssignmentFetchFuture fetchFut = new GridDhtAssignmentFetchFuture(
- cctx,
- desc.groupId(),
- futureToFetchAffinity.topologyVersion(),
- futureToFetchAffinity.events().discoveryCache()
+ cctx,
+ desc.groupId(),
+ futureToFetchAffinity.topologyVersion(),
+ futureToFetchAffinity.events().discoveryCache()
);
fetchFut.init(false);
@@ -2255,13 +2104,13 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
fetchFut.listen(new IgniteInClosureX<IgniteInternalFuture<GridDhtAffinityAssignmentResponse>>() {
@Override public void applyx(IgniteInternalFuture<GridDhtAffinityAssignmentResponse> fetchFut)
- throws IgniteCheckedException {
+ throws IgniteCheckedException {
fetchAffinity(
- futureToFetchAffinity0.topologyVersion(),
- futureToFetchAffinity0.events(),
- futureToFetchAffinity0.events().discoveryCache(),
- aff,
- (GridDhtAssignmentFetchFuture)fetchFut
+ futureToFetchAffinity0.topologyVersion(),
+ futureToFetchAffinity0.events(),
+ futureToFetchAffinity0.events().discoveryCache(),
+ aff,
+ (GridDhtAssignmentFetchFuture)fetchFut
);
aff.calculate(topVer, fut.events(), fut.events().discoveryCache());
@@ -2375,30 +2224,30 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
if (cctx.localNode().isClient() && cctx.cache().cacheGroup(desc.groupId()) == null)
return;
- CacheGroupHolder cache = getOrCreateGroupHolder(evts.topologyVersion(), desc);
+ CacheGroupHolder grpHolder = getOrCreateGroupHolder(evts.topologyVersion(), desc);
- boolean latePrimary = cache.rebalanceEnabled;
+ boolean latePrimary = grpHolder.rebalanceEnabled;
boolean grpAdded = evts.nodeJoined(desc.receivedFrom());
initAffinityOnNodeJoin(evts,
grpAdded,
- cache.affinity(),
+ grpHolder.affinity(),
crd ? waitRebalanceInfo : null,
latePrimary);
if (crd && grpAdded) {
- AffinityAssignment aff = cache.aff.cachedAffinity(cache.aff.lastVersion());
+ AffinityAssignment aff = grpHolder.aff.cachedAffinity(grpHolder.aff.lastVersion());
assert evts.topologyVersion().equals(aff.topologyVersion()) : "Unexpected version [" +
- "grp=" + cache.aff.cacheOrGroupName() +
+ "grp=" + grpHolder.aff.cacheOrGroupName() +
", evts=" + evts.topologyVersion() +
- ", aff=" + cache.aff.lastVersion() + ']';
+ ", aff=" + grpHolder.aff.lastVersion() + ']';
Map<UUID, GridDhtPartitionMap> map = affinityFullMap(aff);
for (GridDhtPartitionMap map0 : map.values())
- cache.topology(fut.context().events().discoveryCache()).update(fut.exchangeId(), map0, true);
+ grpHolder.topology(fut.context().events().discoveryCache()).update(fut.exchangeId(), map0, true);
}
cctx.exchange().exchangerUpdateHeartbeat();
@@ -2466,77 +2315,40 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
assert affTopVer.topologyVersion() > 0 : "Affinity is not initialized [grp=" + aff.cacheOrGroupName() +
", topVer=" + affTopVer + ", node=" + cctx.localNodeId() + ']';
- assert aff.idealAssignmentRaw() != null : "Previous assignment is not available.";
+ List<List<ClusterNode>> curAff = aff.assignments(affTopVer);
+
+ assert aff.idealAssignment() != null : "Previous assignment is not available.";
- IdealAffinityAssignment idealAssignment = aff.calculate(evts.topologyVersion(), evts, evts.discoveryCache());
- List<List<ClusterNode>> curAssignment = aff.assignments(affTopVer);
+ List<List<ClusterNode>> idealAssignment = aff.calculate(evts.topologyVersion(), evts, evts.discoveryCache()).assignment();
List<List<ClusterNode>> newAssignment = null;
if (latePrimary) {
- BitSet processedPartitions = new BitSet(curAssignment.size());
+ for (int p = 0; p < idealAssignment.size(); p++) {
+ List<ClusterNode> newNodes = idealAssignment.get(p);
+ List<ClusterNode> curNodes = curAff.get(p);
- // Late affinity assignment to changed primaries.
- for (ClusterNode joinedNode : evts.joinedServerNodes()) {
- Set<Integer> primaries = idealAssignment.idealPrimaries(joinedNode);
-
- for (int p : primaries) {
- List<ClusterNode> curNodes = curAssignment.get(p);
-
- if (curNodes.isEmpty())
- continue;
-
- ClusterNode curPrimary = curNodes.get(0);
+ ClusterNode curPrimary = !curNodes.isEmpty() ? curNodes.get(0) : null;
+ ClusterNode newPrimary = !newNodes.isEmpty() ? newNodes.get(0) : null;
+ if (curPrimary != null && newPrimary != null && !curPrimary.equals(newPrimary)) {
assert cctx.discovery().node(evts.topologyVersion(), curPrimary.id()) != null : curPrimary;
- List<ClusterNode> idealNodes = idealAssignment.assignment().get(p);
-
- List<ClusterNode> newNodes = latePrimaryAssignment(aff,
+ List<ClusterNode> nodes0 = latePrimaryAssignment(aff,
p,
curPrimary,
- idealNodes,
- rebalanceInfo);
-
- if (newAssignment == null)
- newAssignment = new ArrayList<>(idealAssignment.assignment());
-
- newAssignment.set(p, newNodes);
-
- processedPartitions.set(p);
- }
- }
-
- Set<Integer> partitionsWithChangedPrimary = aff.partitionPrimariesDifferentToIdeal(affTopVer);
-
- for (int p : partitionsWithChangedPrimary) {
- // Already processed above.
- if (processedPartitions.get(p))
- continue;
-
- List<ClusterNode> curNodes = curAssignment.get(p);
-
- if (curNodes.isEmpty())
- continue;
-
- List<ClusterNode> idealOwners = idealAssignment.assignment().get(p);
-
- if (!curNodes.get(0).equals(idealOwners.get(0))) {
- List<ClusterNode> newNodes = latePrimaryAssignment(aff,
- p,
- curNodes.get(0),
- idealOwners,
+ newNodes,
rebalanceInfo);
if (newAssignment == null)
- newAssignment = new ArrayList<>(idealAssignment.assignment());
+ newAssignment = new ArrayList<>(idealAssignment);
- newAssignment.set(p, newNodes);
+ newAssignment.set(p, nodes0);
}
}
}
if (newAssignment == null)
- newAssignment = idealAssignment.assignment();
+ newAssignment = idealAssignment;
aff.initialize(evts.topologyVersion(), newAssignment);
}
@@ -2608,14 +2420,13 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
}
/**
- * Initializes current affinity assignment based on partitions availability.
- * Nodes that have most recent data will be considered affinity nodes.
+ * Initializes current affinity assignment based on partitions availability. Nodes that have most recent data will
+ * be considered affinity nodes.
*
* @param topVer Topology version.
* @param fut Exchange future.
* @param c Closure converting affinity diff.
* @param initAff {@code True} if need initialize affinity.
- *
* @return Affinity assignment for each of registered cache group.
*/
private <T> Map<Integer, Map<Integer, List<T>>> initAffinityBasedOnPartitionsAvailability(
@@ -2989,7 +2800,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
GridCacheSharedContext cctx,
CacheGroupDescriptor grpDesc,
AffinityTopologyVersion topVer
- ) throws IgniteCheckedException {
+ ) throws IgniteCheckedException {
return create(cctx, grpDesc, topVer, null);
}
@@ -3128,14 +2939,13 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
* @param waitNode Node rebalancing data.
* @param assignment New assignment.
*/
- void add(Integer grpId, Integer part, UUID waitNode, List<ClusterNode> assignment) {
- assert !F.isEmpty(assignment) : assignment;
-
+ void add(Integer grpId, Integer part, UUID waitNode, @Nullable List<ClusterNode> assignment) {
deploymentIds.putIfAbsent(grpId, cachesRegistry.group(grpId).deploymentId());
waitGrps.computeIfAbsent(grpId, k -> new HashMap<>()).put(part, waitNode);
- assignments.computeIfAbsent(grpId, k -> new HashMap<>()).put(part, assignment);
+ if (assignment != null)
+ assignments.computeIfAbsent(grpId, k -> new HashMap<>()).put(part, assignment);
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryInfoCollection.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryInfoCollection.java
index 968afd5..b6da77f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryInfoCollection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheEntryInfoCollection.java
@@ -128,4 +128,23 @@ public class CacheEntryInfoCollection implements Message {
@Override public byte fieldsCount() {
return 1;
}
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("[");
+
+ for (int i = 0; i < infos().size(); i++) {
+ GridCacheEntryInfo info = infos().get(i);
+
+ Object k = info.key().value(null, false);
+
+ b.append("[key=").append(k == null ? "null" : k).append(", ver=").
+ append(info.version()).append(", val=").append(info.value()).append(']');
+ }
+
+ b.append(']');
+
+ return b.toString();
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
index 29efa76..68dffbf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
@@ -65,6 +65,7 @@ import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.mxbean.CacheGroupMetricsMXBean;
import org.jetbrains.annotations.Nullable;
+import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT;
import static org.apache.ignite.cache.CacheMode.LOCAL;
import static org.apache.ignite.cache.CacheMode.REPLICATED;
@@ -182,6 +183,8 @@ public class CacheGroupContext {
/** Statistics holder to track IO operations for data pages. */
private final IoStatisticsHolder statHolderData;
+ /** */
+ private volatile boolean hasAtomicCaches;
/**
* @param ctx Context.
@@ -357,6 +360,9 @@ public class CacheGroupContext {
if (!drEnabled && cctx.isDrEnabled())
drEnabled = true;
+
+ if (!hasAtomicCaches)
+ hasAtomicCaches = cctx.config().getAtomicityMode() == ATOMIC;
}
/**
@@ -1278,4 +1284,11 @@ public class CacheGroupContext {
public IoStatisticsHolder statisticsHolderData() {
return statHolderData;
}
+
+ /**
+ * @return {@code True} if group has atomic caches.
+ */
+ public boolean hasAtomicCaches() {
+ return hasAtomicCaches;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 5ca9c41..54dc706 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -1542,10 +1542,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (cctx.deferredDelete() && deletedUnlocked() && !isInternal() && !detached())
deletedUnlocked(false);
- updateCntr0 = nextPartitionCounter(topVer, tx == null || tx.local(), updateCntr);
-
- if (updateCntr != null && updateCntr != 0)
- updateCntr0 = updateCntr;
+ updateCntr0 = nextPartitionCounter(tx, updateCntr);
if (tx != null && cctx.group().persistenceEnabled() && cctx.group().walEnabled())
logPtr = logTxUpdate(tx, val, expireTime, updateCntr0);
@@ -1765,10 +1762,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
}
- updateCntr0 = nextPartitionCounter(topVer, tx == null || tx.local(), updateCntr);
-
- if (updateCntr != null && updateCntr != 0)
- updateCntr0 = updateCntr;
+ updateCntr0 = nextPartitionCounter(tx, updateCntr);
if (tx != null && cctx.group().persistenceEnabled() && cctx.group().walEnabled())
logPtr = logTxUpdate(tx, null, 0, updateCntr0);
@@ -2189,7 +2183,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
cctx.cache().metrics0().onInvokeRemove(old != null);
if (lsnrCol != null) {
- long updateCntr = nextPartitionCounter(AffinityTopologyVersion.NONE, true, null);
+ long updateCntr = nextPartitionCounter(AffinityTopologyVersion.NONE, true, false, null);
cctx.continuousQueries().onEntryUpdated(
lsnrCol,
@@ -2368,12 +2362,9 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
else
evtVal = (CacheObject)writeObj;
- long updateCntr0 = nextPartitionCounter(topVer, primary, updateCntr);
+ assert !primary && updateCntr != null;
- if (updateCntr != null)
- updateCntr0 = updateCntr;
-
- onUpdateFinished(updateCntr0);
+ onUpdateFinished(updateCntr);
cctx.continuousQueries().onEntryUpdated(
key,
@@ -2383,7 +2374,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
partition(),
primary,
false,
- updateCntr0,
+ updateCntr,
null,
topVer);
}
@@ -3447,7 +3438,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
long updateCntr = 0;
if (!preload)
- updateCntr = nextPartitionCounter(topVer, true, null);
+ updateCntr = nextPartitionCounter(topVer, true, true, null);
if (walEnabled) {
if (cctx.mvccEnabled()) {
@@ -3536,10 +3527,20 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
/**
* @param topVer Topology version for current operation.
* @param primary Primary node update flag.
+ * @param initial {@code True} if initial value.
* @param primaryCntr Counter assigned on primary node.
* @return Update counter.
*/
- protected long nextPartitionCounter(AffinityTopologyVersion topVer, boolean primary, @Nullable Long primaryCntr) {
+ protected long nextPartitionCounter(AffinityTopologyVersion topVer, boolean primary, boolean initial,
+ @Nullable Long primaryCntr) {
+ return 0;
+ }
+
+ /**
+ * @param tx Tx.
+ * @param updateCntr Update counter.
+ */
+ protected long nextPartitionCounter(IgniteInternalTx tx, @Nullable Long updateCntr) {
return 0;
}
@@ -5574,8 +5575,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
cctx.cacheId(),
entry.key(),
val,
- res.resultType() == ResultType.PREV_NULL ? CREATE :
- (res.resultType() == ResultType.REMOVED_NOT_NULL) ? DELETE : UPDATE,
+ res.resultType() == ResultType.PREV_NULL ? CREATE :
+ (res.resultType() == ResultType.REMOVED_NOT_NULL) ? DELETE : UPDATE,
tx.nearXidVersion(),
newVer,
expireTime,
@@ -5751,7 +5752,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
oldRow);
treeOp = oldRow != null && oldRow.link() == newRow.link() ?
- IgniteTree.OperationType.NOOP : IgniteTree.OperationType.PUT;
+ IgniteTree.OperationType.IN_PLACE : IgniteTree.OperationType.PUT;
}
else
treeOp = oldRow != null ? IgniteTree.OperationType.REMOVE : IgniteTree.OperationType.NOOP;
@@ -6376,10 +6377,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
", locNodeId=" + cctx.localNodeId() + ']';
}
- long updateCntr0 = entry.nextPartitionCounter(topVer, primary, updateCntr);
-
- if (updateCntr != null)
- updateCntr0 = updateCntr;
+ long updateCntr0 = entry.nextPartitionCounter(topVer, primary, false, updateCntr);
entry.logUpdate(op, updated, newVer, newExpireTime, updateCntr0);
@@ -6466,10 +6464,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
// Must persist inside synchronization in non-tx mode.
cctx.store().remove(null, entry.key);
- long updateCntr0 = entry.nextPartitionCounter(topVer, primary, updateCntr);
-
- if (updateCntr != null)
- updateCntr0 = updateCntr;
+ long updateCntr0 = entry.nextPartitionCounter(topVer, primary, false, updateCntr);
entry.logUpdate(op, null, newVer, 0, updateCntr0);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 199f725..f5ba7a2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -1773,7 +1773,9 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
null,
msg.partsToReload(cctx.localNodeId(), grpId),
partsSizes.getOrDefault(grpId, Collections.emptyMap()),
- msg.topologyVersion());
+ msg.topologyVersion(),
+ null
+ );
}
}
@@ -1815,8 +1817,8 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
try {
if (msg.exchangeId() == null) {
- if (log.isTraceEnabled())
- log.trace("Received local partition update [nodeId=" + node.id() + ", parts=" +
+ if (log.isDebugEnabled())
+ log.debug("Received local partition update [nodeId=" + node.id() + ", parts=" +
msg + ']');
boolean updated = false;
@@ -1865,7 +1867,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
U.warn(log, "Client node tries to connect but its exchange " +
"info is cleaned up from exchange history. " +
"Consider increasing 'IGNITE_EXCHANGE_HISTORY_SIZE' property " +
- "or start clients in smaller batches. " +
+ "or start clients in smaller batches. " +
"Current settings and versions: " +
"[IGNITE_EXCHANGE_HISTORY_SIZE=" + EXCHANGE_HISTORY_SIZE + ", " +
"initVer=" + initVer + ", " +
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 48797ee..ec4b8cf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -119,7 +119,6 @@ import org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaS
import org.apache.ignite.internal.processors.cache.persistence.metastorage.MetastorageLifecycleListener;
import org.apache.ignite.internal.processors.cache.persistence.metastorage.ReadOnlyMetastorage;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
-import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionRecoverState;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteCacheSnapshotManager;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotDiscoveryMessage;
import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
@@ -236,6 +235,10 @@ public class GridCacheProcessor extends GridProcessorAdapter {
private static final String INVALID_REGION_CONFIGURATION_MESSAGE = "Failed to join node " +
"(Incompatible data region configuration [region=%s, locNodeId=%s, isPersistenceEnabled=%s, rmtNodeId=%s, isPersistenceEnabled=%s])";
+ /** Template of message of failed node join because encryption settings are different for the same cache. */
+ private static final String ENCRYPT_MISMATCH_MESSAGE = "Failed to join node to the cluster " +
+ "(encryption settings are different for cache '%s' : local=%s, remote=%s.)";
+
/** */
private final boolean startClientCaches =
IgniteSystemProperties.getBoolean(IgniteSystemProperties.IGNITE_START_CACHES_ON_JOIN, false);
@@ -1069,7 +1072,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
}
/**
- * @param node Remote node to check.
+ * @param rmtNode Remote node to check.
* @return Data storage configuration
*/
private DataStorageConfiguration extractDataStorage(ClusterNode rmtNode) {
@@ -3489,12 +3492,12 @@ public class GridCacheProcessor extends GridProcessorAdapter {
}
}
- DynamicCacheDescriptor localDesc = cacheDescriptor(cacheInfo.cacheData().config().getName());
+ DynamicCacheDescriptor locDesc = cacheDescriptor(cacheInfo.cacheData().config().getName());
- if (localDesc == null)
+ if (locDesc == null)
continue;
- QuerySchemaPatch schemaPatch = localDesc.makeSchemaPatch(cacheInfo.cacheData().queryEntities());
+ QuerySchemaPatch schemaPatch = locDesc.makeSchemaPatch(cacheInfo.cacheData().queryEntities());
if (schemaPatch.hasConflicts() || (isGridActive && !schemaPatch.isEmpty())) {
if (errorMsg.length() > 0)
@@ -3502,9 +3505,22 @@ public class GridCacheProcessor extends GridProcessorAdapter {
if (schemaPatch.hasConflicts())
errorMsg.append(String.format(MERGE_OF_CONFIG_CONFLICTS_MESSAGE,
- localDesc.cacheName(), schemaPatch.getConflictsMessage()));
+ locDesc.cacheName(), schemaPatch.getConflictsMessage()));
else
- errorMsg.append(String.format(MERGE_OF_CONFIG_REQUIRED_MESSAGE, localDesc.cacheName()));
+ errorMsg.append(String.format(MERGE_OF_CONFIG_REQUIRED_MESSAGE, locDesc.cacheName()));
+ }
+
+ // This check must be done on join, otherwise group encryption key will be
+ // written to metastore regardless of validation check and could trigger WAL write failures.
+ boolean locEnc = locDesc.cacheConfiguration().isEncryptionEnabled();
+ boolean rmtEnc = cacheInfo.cacheData().config().isEncryptionEnabled();
+
+ if (locEnc != rmtEnc) {
+ if (errorMsg.length() > 0)
+ errorMsg.append("\n");
+
+ // Message will be printed on remote node, so need to swap local and remote.
+ errorMsg.append(String.format(ENCRYPT_MISMATCH_MESSAGE, locDesc.cacheName(), rmtEnc, locEnc));
}
}
@@ -6016,7 +6032,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
*/
private void restorePartitionStates(
Collection<CacheGroupContext> forGroups,
- Map<GroupPartitionId, PartitionRecoverState> partitionStates
+ Map<GroupPartitionId, Integer> partitionStates
) throws IgniteCheckedException {
long startRestorePart = U.currentTimeMillis();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedTtlCleanupManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedTtlCleanupManager.java
index 2254c5e..3623fd9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedTtlCleanupManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedTtlCleanupManager.java
@@ -23,6 +23,7 @@ import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.failure.FailureContext;
import org.apache.ignite.internal.IgniteInterruptedCheckedException;
import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.NodeStoppingException;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.util.worker.GridWorker;
import org.apache.ignite.thread.IgniteThread;
@@ -164,7 +165,13 @@ public class GridCacheSharedTtlCleanupManager extends GridCacheSharedManagerAdap
}
}
catch (Throwable t) {
- if (!(X.hasCause(t, IgniteInterruptedCheckedException.class, InterruptedException.class)))
+ if (X.hasCause(t, NodeStoppingException.class)) {
+ isCancelled = true; // Treat node stopping as valid worker cancellation.
+
+ return;
+ }
+
+ if (!(t instanceof IgniteInterruptedCheckedException || t instanceof InterruptedException))
err = t;
throw t;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index 48c86b9..cc5dd42 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -849,6 +849,7 @@ public class GridCacheUtils {
return tx.getClass().getSimpleName() + "[xid=" + tx.xid() +
", xidVersion=" + tx.xidVersion() +
+ ", nearXidVersion=" + tx.nearXidVersion() +
", concurrency=" + tx.concurrency() +
", isolation=" + tx.isolation() +
", state=" + tx.state() +
@@ -857,7 +858,7 @@ public class GridCacheUtils {
", nodeId=" + tx.nodeId() +
", timeout=" + tx.timeout() +
", duration=" + (U.currentTimeMillis() - tx.startTime()) +
- (tx instanceof GridNearTxLocal ? ", label=" + ((GridNearTxLocal)tx).label() : "") +
+ (tx instanceof GridNearTxLocal ? ", label=" + tx.label() : "") +
']';
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
index b7e8ec7..74a0b30 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
@@ -31,8 +31,9 @@ import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
import org.apache.ignite.internal.processors.cache.persistence.CacheSearchRow;
import org.apache.ignite.internal.processors.cache.persistence.RootPage;
import org.apache.ignite.internal.processors.cache.persistence.RowStore;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
-import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionRecoverState;
+import org.apache.ignite.internal.processors.cache.persistence.partstorage.PartitionMetaStorage;
import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
import org.apache.ignite.internal.processors.cache.tree.PendingEntriesTree;
import org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccUpdateResult;
@@ -90,7 +91,7 @@ public interface IgniteCacheOffheapManager {
* @return Number of processed partitions.
* @throws IgniteCheckedException If failed.
*/
- long restorePartitionStates(Map<GroupPartitionId, PartitionRecoverState> partitionRecoveryStates) throws IgniteCheckedException;
+ long restorePartitionStates(Map<GroupPartitionId, Integer> partitionRecoveryStates) throws IgniteCheckedException;
/**
* Partition counter update callback. May be overridden by plugin-provided subclasses.
@@ -104,9 +105,10 @@ public interface IgniteCacheOffheapManager {
* Initial counter will be updated on state restore only
*
* @param part Partition
- * @param cntr New initial counter
+ * @param start Start.
+ * @param delta Delta.
*/
- public void onPartitionInitialCounterUpdated(int part, long cntr);
+ public void onPartitionInitialCounterUpdated(int part, long start, long delta);
/**
* Partition counter provider. May be overridden by plugin-provided subclasses.
@@ -584,6 +586,13 @@ public interface IgniteCacheOffheapManager {
*/
interface CacheDataStore {
/**
+ * Initialize data store if it exists.
+ *
+ * @return {@code True} if initialized.
+ */
+ boolean init();
+
+ /**
* @return Partition ID.
*/
int partId();
@@ -594,13 +603,6 @@ public interface IgniteCacheOffheapManager {
String name();
/**
- * @param size Size to init.
- * @param updCntr Update counter to init.
- * @param cacheSizes Cache sizes if store belongs to group containing multiple caches.
- */
- void init(long size, long updCntr, @Nullable Map<Integer, Long> cacheSizes);
-
- /**
* @param cacheId Cache ID.
* @return Size.
*/
@@ -630,22 +632,36 @@ public interface IgniteCacheOffheapManager {
void updateSize(int cacheId, long delta);
/**
- * @return Update counter.
+ * @return Update counter (LWM).
*/
long updateCounter();
/**
+ * @return Reserved counter (HWM).
+ */
+ long reservedCounter();
+
+ /**
+ * @return Update counter or {@code null} if store is not yet created.
+ */
+ @Nullable PartitionUpdateCounter partUpdateCounter();
+
+ /**
+ * @param delta Delta.
+ */
+ long reserve(long delta);
+
+ /**
* @param val Update counter.
*/
void updateCounter(long val);
/**
* Updates counters from start value by delta value.
- *
* @param start Start.
- * @param delta Delta
+ * @param delta Delta.
*/
- void updateCounter(long start, long delta);
+ boolean updateCounter(long start, long delta);
/**
* @return Next update counter.
@@ -1017,9 +1033,10 @@ public interface IgniteCacheOffheapManager {
public RowStore rowStore();
/**
- * @param cntr Counter.
+ * @param start Counter.
+ * @param delta Delta.
*/
- public void updateInitialCounter(long cntr);
+ public void updateInitialCounter(long start, long delta);
/**
* Inject rows cache cleaner.
@@ -1047,5 +1064,15 @@ public interface IgniteCacheOffheapManager {
* @throws IgniteCheckedException If failed.
*/
public void preload() throws IgniteCheckedException;
+
+ /**
+ * Reset counters for partition.
+ */
+ void resetUpdateCounter();
+
+ /**
+ * Partition storage.
+ */
+ public PartitionMetaStorage<SimpleDataRow> partStorage();
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index a0ebcdc..3706754 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -36,6 +36,9 @@ import javax.cache.processor.EntryProcessor;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.failure.FailureContext;
+import org.apache.ignite.failure.FailureType;
import org.apache.ignite.internal.NodeStoppingException;
import org.apache.ignite.internal.pagemem.FullPageId;
import org.apache.ignite.internal.pagemem.wal.record.delta.DataPageMvccMarkUpdatedRecord;
@@ -59,8 +62,9 @@ import org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapt
import org.apache.ignite.internal.processors.cache.persistence.CacheSearchRow;
import org.apache.ignite.internal.processors.cache.persistence.RootPage;
import org.apache.ignite.internal.processors.cache.persistence.RowStore;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
-import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionRecoverState;
+import org.apache.ignite.internal.processors.cache.persistence.partstorage.PartitionMetaStorage;
import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO;
@@ -139,6 +143,10 @@ import static org.apache.ignite.internal.util.IgniteTree.OperationType.PUT;
*/
public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager {
/** */
+ private final boolean failNodeOnPartitionInconsistency = Boolean.getBoolean(
+ IgniteSystemProperties.IGNITE_FAIL_NODE_ON_UNRECOVERABLE_PARTITION_INCONSISTENCY);
+
+ /** */
protected GridCacheSharedContext ctx;
/** */
@@ -251,7 +259,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
}
/** {@inheritDoc} */
- @Override public long restorePartitionStates(Map<GroupPartitionId, PartitionRecoverState> partitionRecoveryStates) throws IgniteCheckedException {
+ @Override public long restorePartitionStates(Map<GroupPartitionId, Integer> partitionRecoveryStates) throws IgniteCheckedException {
return 0; // No-op.
}
@@ -692,7 +700,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
}
/** {@inheritDoc} */
- @Override public void onPartitionInitialCounterUpdated(int part, long cntr) {
+ @Override public void onPartitionInitialCounterUpdated(int part, long start, long delta) {
// No-op.
}
@@ -1398,7 +1406,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
private final CacheDataTree dataTree;
/** Update counter. */
- protected final PartitionUpdateCounter pCntr = new PartitionUpdateCounter(log);
+ protected final PartitionUpdateCounter pCntr;
/** Partition size. */
private final AtomicLong storageSize = new AtomicLong();
@@ -1431,6 +1439,14 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
this.name = name;
this.rowStore = rowStore;
this.dataTree = dataTree;
+ if (grp.mvccEnabled())
+ pCntr = new PartitionMvccTxUpdateCounterImpl();
+ else if (grp.hasAtomicCaches())
+ pCntr = new PartitionAtomicUpdateCounterImpl();
+ else {
+ pCntr = ctx.logger(PartitionTxUpdateCounterDebugWrapper.class).isDebugEnabled() ?
+ new PartitionTxUpdateCounterDebugWrapper(grp, partId) : new PartitionTxUpdateCounterImpl();
+ }
}
/**
@@ -1448,6 +1464,11 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
}
/** {@inheritDoc} */
+ @Override public boolean init() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
@Override public int partId() {
return partId;
}
@@ -1527,14 +1548,17 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
return pCntr.initial();
}
- /** {@inheritDoc} */
- @Override public void updateInitialCounter(long cntr) {
- pCntr.updateInitial(cntr);
+ /** {@inheritDoc}
+ * @param start Start.
+ * @param delta Delta.
+ */
+ @Override public void updateInitialCounter(long start, long delta) {
+ pCntr.updateInitial(start, delta);
}
/** {@inheritDoc} */
@Override public long getAndIncrementUpdateCounter(long delta) {
- return pCntr.getAndAdd(delta);
+ return pCntr.reserve(delta);
}
/** {@inheritDoc} */
@@ -1543,13 +1567,39 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
}
/** {@inheritDoc} */
+ @Override public long reservedCounter() {
+ return pCntr.reserved();
+ }
+
+ /** {@inheritDoc} */
+ @Override public PartitionUpdateCounter partUpdateCounter() {
+ return pCntr;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long reserve(long delta) {
+ return pCntr.reserve(delta);
+ }
+
+ /** {@inheritDoc} */
@Override public void updateCounter(long val) {
- pCntr.update(val);
+ try {
+ pCntr.update(val);
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to update partition counter. " +
+ "Most probably a node with most actual data is out of topology or data streamer is used " +
+ "in preload mode (allowOverride=false) concurrently with cache transactions [grpName=" +
+ grp.name() + ", partId=" + partId + ']', e);
+
+ if (failNodeOnPartitionInconsistency)
+ ctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
+ }
}
/** {@inheritDoc} */
- @Override public void updateCounter(long start, long delta) {
- pCntr.update(start, delta);
+ @Override public boolean updateCounter(long start, long delta) {
+ return pCntr.update(start, delta);
}
/** {@inheritDoc} */
@@ -1638,6 +1688,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
}
case NOOP:
+ case IN_PLACE:
break;
default:
@@ -2891,9 +2942,14 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
rowStore().setRowCacheCleaner(rowCacheCleaner);
}
- /** {@inheritDoc} */
- @Override public void init(long size, long updCntr, @Nullable Map<Integer, Long> cacheSizes) {
- pCntr.init(updCntr);
+ /**
+ * @param size Size to init.
+ * @param updCntr Update counter.
+ * @param cacheSizes Cache sizes if store belongs to group containing multiple caches.
+ * @param cntrUpdData Counter updates.
+ */
+ public void restoreState(long size, long updCntr, @Nullable Map<Integer, Long> cacheSizes, byte[] cntrUpdData) {
+ pCntr.init(updCntr, cntrUpdData);
storageSize.set(size);
@@ -2913,6 +2969,16 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
// No-op.
}
+ /** {@inheritDoc} */
+ @Override public void resetUpdateCounter() {
+ pCntr.reset();
+ }
+
+ /** {@inheritDoc} */
+ @Override public PartitionMetaStorage<SimpleDataRow> partStorage() {
+ return null;
+ }
+
/**
* @param cctx Cache context.
* @param key Key.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionAtomicUpdateCounterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionAtomicUpdateCounterImpl.java
new file mode 100644
index 0000000..317c679
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionAtomicUpdateCounterImpl.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.util.GridEmptyIterator;
+import org.apache.ignite.internal.util.GridLongList;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Partition update counter for non-tx scenarios without support for tracking missed updates.
+ * TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11797
+ */
+public class PartitionAtomicUpdateCounterImpl implements PartitionUpdateCounter {
+ /** Counter of applied updates in partition. */
+ private final AtomicLong cntr = new AtomicLong();
+
+ /**
+ * Initial counter is set to update with max sequence number after WAL recovery.
+ */
+ private long initCntr;
+
+ /** {@inheritDoc} */
+ @Override public void init(long initUpdCntr, @Nullable byte[] cntrUpdData) {
+ cntr.set(initUpdCntr);
+
+ initCntr = initUpdCntr;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long initial() {
+ return initCntr;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long get() {
+ return cntr.get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long next() {
+ return cntr.incrementAndGet();
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override public void update(long val) {
+ long cur;
+
+ while(val > (cur = cntr.get()) && !cntr.compareAndSet(cur, val));
+ }
+
+ /**
+ * Updates counter by delta from start position.
+ *
+ * @param start Start.
+ * @param delta Delta.
+ */
+ @Override public boolean update(long start, long delta) {
+ return false; // Prevent RollbackRecord in mixed tx-atomic mode.
+ }
+
+ /**
+ * Updates initial counter on recovery. Not thread-safe.
+ *
+ * @param start Start.
+ * @param delta Delta.
+ */
+ @Override public synchronized void updateInitial(long start, long delta) {
+ update(start + delta);
+
+ initCntr = get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridLongList finalizeUpdateCounters() {
+ return new GridLongList(0);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long reserve(long delta) {
+ return next(delta);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long next(long delta) {
+ return cntr.getAndAdd(delta);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sequential() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public @Nullable byte[] getBytes() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized void reset() {
+ initCntr = 0;
+
+ cntr.set(0);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ PartitionAtomicUpdateCounterImpl cntr = (PartitionAtomicUpdateCounterImpl)o;
+
+ return this.cntr.get() == cntr.cntr.get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long reserved() {
+ return get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized boolean empty() {
+ return get() == 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterator<long[]> iterator() {
+ return new GridEmptyIterator<>();
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "Counter [init=" + initCntr + ", val=" + get() + ']';
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionMvccTxUpdateCounterImpl.java
similarity index 50%
copy from modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
copy to modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionMvccTxUpdateCounterImpl.java
index 133f0a1..2f5d77a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionMvccTxUpdateCounterImpl.java
@@ -15,38 +15,19 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.persistence;
-
-import org.apache.ignite.IgniteCheckedException;
+package org.apache.ignite.internal.processors.cache;
/**
- * Simple interface for data, store in some RowStore.
+ * Update counter implementation for MVCC mode.
*/
-public interface Storable {
- /**
- * @param link Link for this row.
- */
- public void link(long link);
-
- /**
- * @return Link for this row.
- */
- public long link();
-
- /**
- * @return Partition.
- */
- public int partition();
-
- /**
- * @return Row size in page.
- * @throws IgniteCheckedException If failed.
- */
- public int size() throws IgniteCheckedException;
+public class PartitionMvccTxUpdateCounterImpl extends PartitionTxUpdateCounterImpl {
+ /** {@inheritDoc} */
+ @Override public long reserve(long delta) {
+ return next(delta);
+ }
- /**
- * @return Row header size in page. Header is indivisible part of row
- * which is entirely available on the very first page followed by the row link.
- */
- public int headerSize();
+ /** {@inheritDoc} */
+ @Override public long reserved() {
+ return get();
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionTxUpdateCounterDebugWrapper.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionTxUpdateCounterDebugWrapper.java
new file mode 100644
index 0000000..a63479b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionTxUpdateCounterDebugWrapper.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.util.GridLongList;
+import org.apache.ignite.internal.util.typedef.internal.SB;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Update counter implementation useful for debugging.
+ */
+public class PartitionTxUpdateCounterDebugWrapper extends PartitionTxUpdateCounterImpl {
+ /** */
+ private IgniteLogger log;
+
+ /** */
+ private int partId;
+
+ /** */
+ private CacheGroupContext grp;
+
+ /**
+ * @param grp Group.
+ * @param partId Part id.
+ */
+ public PartitionTxUpdateCounterDebugWrapper(CacheGroupContext grp, int partId) {
+ this.log = grp.shared().logger(getClass());
+ this.partId = partId;
+ this.grp = grp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void init(long initUpdCntr, @Nullable byte[] cntrUpdData) {
+ super.init(initUpdCntr, cntrUpdData);
+
+ log.debug("[op=init" +
+ ", grpId=" + grp.groupId() +
+ ", grpName=" + grp.cacheOrGroupName() +
+ ", caches=" + grp.caches() +
+ ", atomicity=" + grp.config().getAtomicityMode() +
+ ", syncMode=" + grp.config().getWriteSynchronizationMode() +
+ ", mode=" + grp.config().getCacheMode() +
+ ", partId=" + partId +
+ ", gapsLen=" + (cntrUpdData != null ? cntrUpdData.length : 0) +
+ ", cur=" + toString() +
+ ']');
+ }
+
+ /** {@inheritDoc} */
+ @Override public void updateInitial(long start, long delta) {
+ SB sb = new SB();
+
+ sb.a("[op=updateInitial" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", range=(" + start + "," + delta + ")" +
+ ", before=" + toString());
+
+ try {
+ super.updateInitial(start, delta);
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public long next() {
+ SB sb = new SB();
+
+ sb.a("[op=next" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", before=" + toString());
+
+ try {
+ return super.next();
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public long next(long delta) {
+ SB sb = new SB();
+
+ sb.a("[op=next" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", delta=" + delta +
+ ", before=" + toString());
+
+ try {
+ return super.next();
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized void update(long val) throws IgniteCheckedException {
+ SB sb = new SB();
+
+ sb.a("[op=set" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", val=" + val +
+ ", before=" + toString());
+
+ try {
+ super.update(val);
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized GridLongList finalizeUpdateCounters() {
+ SB sb = new SB();
+
+ sb.a("[op=finalizeUpdateCounters" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", before=" + toString() +
+ ']');
+
+ try {
+ return super.finalizeUpdateCounters();
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized long reserve(long delta) {
+ SB sb = new SB();
+
+ sb.a("[op=reserve" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", delta=" + delta +
+ ", before=" + toString());
+
+ try {
+ return super.reserve(delta);
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized boolean update(long start, long delta) {
+ SB sb = new SB();
+
+ sb.a("[op=update" +
+ ", grpId=" + grp.groupId() +
+ ", partId=" + partId +
+ ", delta=(" + start + "," + delta + ")" +
+ ", before=" + toString());
+
+ boolean updated = false;
+
+ try {
+ updated = super.update(start, delta);
+ }
+ finally {
+ log.debug(sb.a(", after=" + toString() +
+ ']').toString());
+ }
+
+ return updated;
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionTxUpdateCounterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionTxUpdateCounterImpl.java
new file mode 100644
index 0000000..f8f236f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionTxUpdateCounterImpl.java
@@ -0,0 +1,450 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl;
+import org.apache.ignite.internal.util.GridLongList;
+import org.apache.ignite.internal.util.typedef.F;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Update counter implementation used for transactional cache groups.
+ */
+public class PartitionTxUpdateCounterImpl implements PartitionUpdateCounter {
+ /**
+ * Max allowed missed updates. Overflow will trigger critical failure handler to prevent OOM.
+ */
+ public static final int MAX_MISSED_UPDATES = 10_000;
+
+ /** Counter updates serialization version. */
+ private static final byte VERSION = 1;
+
+ /** Queue of finished out of order counter updates. */
+ private TreeSet<Item> queue = new TreeSet<>();
+
+ /** LWM. */
+ private final AtomicLong cntr = new AtomicLong();
+
+ /** HWM. */
+ private final AtomicLong reserveCntr = new AtomicLong();
+
+ /**
+ * Initial counter points to last sequential update after WAL recovery.
+ * @deprecated TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11794
+ */
+ @Deprecated private long initCntr;
+
+ /** {@inheritDoc} */
+ @Override public void init(long initUpdCntr, @Nullable byte[] cntrUpdData) {
+ cntr.set(initUpdCntr);
+
+ initCntr = initUpdCntr;
+
+ queue = fromBytes(cntrUpdData);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long initial() {
+ return initCntr;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long get() {
+ return cntr.get();
+ }
+
+ /** */
+ protected synchronized long highestAppliedCounter() {
+ return queue.isEmpty() ? cntr.get() : queue.last().absolute();
+ }
+
+ /**
+ * @return Next update counter. For tx mode called by {@link DataStreamerImpl} IsolatedUpdater.
+ */
+ @Override public long next() {
+ long next = cntr.incrementAndGet();
+
+ reserveCntr.set(next);
+
+ return next;
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized void update(long val) throws IgniteCheckedException {
+ // Absolute counter should be not less than last applied update.
+ // Otherwise supplier doesn't contain some updates and rebalancing couldn't restore consistency.
+ // Best behavior is to stop node by failure handler in such a case.
+ if (!gaps().isEmpty() && val < highestAppliedCounter())
+ throw new IgniteCheckedException("New value is incompatible with current update counter state. " +
+ "Most probably a node with most actual data is out of topology or data streamer is used in isolated " +
+ "mode (allowOverride=true) concurrently with normal cache operations [val=" + val +
+ ", locCntr=" + this + ']');
+
+ long cur = cntr.get();
+
+ // Reserved update counter is updated only on exchange or in non-tx mode.
+ reserveCntr.set(Math.max(cur, val));
+
+ if (val <= cur)
+ return;
+
+ cntr.set(val);
+
+ if (!queue.isEmpty())
+ queue.clear();
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized boolean update(long start, long delta) {
+ long cur = cntr.get(), next;
+
+ if (cur > start)
+ return false;
+
+ if (cur < start) {
+ // Try merge with adjacent gaps in sequence.
+ Item tmp = new Item(start, delta);
+ Item ref = tmp;
+
+ NavigableSet<Item> set = queue.headSet(tmp, false);
+
+ // Merge with previous, possibly modifying previous.
+ if (!set.isEmpty()) {
+ Item last = set.last();
+
+ if (last.start + last.delta == start) {
+ tmp = last;
+
+ last.delta += delta;
+ }
+ else if (last.within(start) && last.within(start + delta - 1))
+ return false;
+ }
+
+ // Merge with next, possibly modifying previous and removing next.
+ if (!(set = queue.tailSet(tmp, false)).isEmpty()) {
+ Item first = set.first();
+
+ if (tmp.start + tmp.delta == first.start) {
+ if (ref != tmp) {
+ tmp.delta += first.delta;
+
+ set.pollFirst(); // Merge and remove obsolete head.
+ }
+ else {
+ tmp = first;
+
+ first.start = start;
+ first.delta += delta;
+ }
+ }
+ }
+
+ if (tmp != ref)
+ return true;
+
+ return offer(new Item(start, delta)); // backup node with gaps
+ }
+
+ while (true) {
+ boolean res = cntr.compareAndSet(cur, next = start + delta);
+
+ assert res;
+
+ Item peek = peek();
+
+ if (peek == null || peek.start != next)
+ return true;
+
+ Item item = poll();
+
+ assert peek == item;
+
+ start = item.start;
+ delta = item.delta;
+ cur = next;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void updateInitial(long start, long delta) {
+ long cntr0 = get();
+
+ assert start >= cntr0 : "Illegal update counters order: cur=" + cntr0 + ", new=" + start;
+
+ update(start, delta);
+
+ initCntr = get();
+ }
+
+ /** */
+ private Item poll() {
+ return queue.pollFirst();
+ }
+
+ /** */
+ private Item peek() {
+ return queue.isEmpty() ? null : queue.first();
+ }
+
+ /**
+ * @param item Item.
+ */
+ private boolean offer(Item item) {
+ if (queue.size() == MAX_MISSED_UPDATES) // Should trigger failure handler.
+ throw new IgniteException("Too many gaps [cntr=" + this + ']');
+
+ return queue.add(item);
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized GridLongList finalizeUpdateCounters() {
+ Item item = poll();
+
+ GridLongList gaps = null;
+
+ while (item != null) {
+ if (gaps == null)
+ gaps = new GridLongList((queue.size() + 1) * 2);
+
+ long start = cntr.get() + 1;
+ long end = item.start;
+
+ gaps.add(start);
+ gaps.add(end);
+
+ // Close pending ranges.
+ cntr.set(item.start + item.delta);
+
+ item = poll();
+ }
+
+ return gaps;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long reserve(long delta) {
+ long cntr = get();
+
+ long reserved = reserveCntr.getAndAdd(delta);
+
+ assert reserved >= cntr : "LWM after HWM: lwm=" + cntr + ", hwm=" + reserved;
+
+ return reserved;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long next(long delta) {
+ return cntr.getAndAdd(delta);
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized boolean sequential() {
+ return gaps().isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized @Nullable byte[] getBytes() {
+ if (queue.isEmpty())
+ return null;
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ DataOutputStream dos = new DataOutputStream(bos);
+
+ dos.writeByte(VERSION);
+
+ int size = queue.size();
+
+ dos.writeInt(size);
+
+ for (Item item : queue) {
+ dos.writeLong(item.start);
+ dos.writeLong(item.delta);
+ }
+
+ bos.close();
+
+ return bos.toByteArray();
+ }
+ catch (IOException e) {
+ throw new IgniteException(e);
+ }
+ }
+
+ /**
+ * @param raw Raw bytes.
+ */
+ private @Nullable TreeSet<Item> fromBytes(@Nullable byte[] raw) {
+ if (raw == null)
+ return new TreeSet<>();
+
+ TreeSet<Item> ret = new TreeSet<>();
+
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(raw);
+
+ DataInputStream dis = new DataInputStream(bis);
+
+ dis.readByte(); // Version.
+
+ int cnt = dis.readInt(); // Holes count.
+
+ while(cnt-- > 0)
+ ret.add(new Item(dis.readLong(), dis.readLong()));
+
+ return ret;
+ }
+ catch (IOException e) {
+ throw new IgniteException(e);
+ }
+ }
+
+ /** */
+ private TreeSet<Item> gaps() {
+ return queue;
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized void reset() {
+ cntr.set(0);
+
+ reserveCntr.set(0);
+
+ queue = new TreeSet<>();
+ }
+
+ /**
+ * Update counter task. Update from start value by delta value.
+ */
+ private static class Item implements Comparable<Item> {
+ /** */
+ private long start;
+
+ /** */
+ private long delta;
+
+ /**
+ * @param start Start value.
+ * @param delta Delta value.
+ */
+ private Item(long start, long delta) {
+ this.start = start;
+ this.delta = delta;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int compareTo(@NotNull Item o) {
+ return Long.compare(this.start, o.start);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "Item [" +
+ "start=" + start +
+ ", delta=" + delta +
+ ']';
+ }
+
+ /** */
+ public long start() {
+ return start;
+ }
+
+ /** */
+ public long delta() {
+ return delta;
+ }
+
+ /** */
+ public long absolute() {
+ return start + delta;
+ }
+
+ /** */
+ public boolean within(long cntr) {
+ return cntr - start < delta;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ Item item = (Item)o;
+
+ if (start != item.start)
+ return false;
+
+ return (delta != item.delta);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ PartitionTxUpdateCounterImpl cntr = (PartitionTxUpdateCounterImpl)o;
+
+ if (!queue.equals(cntr.queue))
+ return false;
+
+ return this.cntr.get() == cntr.cntr.get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long reserved() {
+ return reserveCntr.get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized boolean empty() {
+ return get() == 0 && sequential();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterator<long[]> iterator() {
+ return F.iterator(queue.iterator(), item -> {
+ return new long[] {item.start, item.delta};
+ }, true);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "Counter [lwm=" + get() + ", holes=" + queue +
+ ", maxApplied=" + highestAppliedCounter() + ", hwm=" + reserveCntr.get() + ']';
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionUpdateCounter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionUpdateCounter.java
old mode 100644
new mode 100755
index 39d8d5f..64aff27
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionUpdateCounter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/PartitionUpdateCounter.java
@@ -17,219 +17,116 @@
package org.apache.ignite.internal.processors.cache;
-import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicLong;
-import org.apache.ignite.IgniteLogger;
+import java.util.Iterator;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.util.GridLongList;
-import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
- * Partition update counter with MVCC delta updates capabilities.
+ * Partition update counter maintains three entities for tracking partition update state.
+ <ol>
+ * <li><b>Low water mark (LWM)</b> or update counter - lowest applied sequential update number.</li>
+ * <li><b>High water mark (HWM)</b> or reservation counter - highest seen but unapplied yet update number.</li>
+ * <li>Out-of-order applied updates in range between LWM and HWM.</li>
+ * </ol>
*/
-public class PartitionUpdateCounter {
- /** */
- private IgniteLogger log;
-
- /** Queue of counter update tasks*/
- private final TreeSet<Item> queue = new TreeSet<>();
-
- /** Counter. */
- private final AtomicLong cntr = new AtomicLong();
-
- /** Initial counter. */
- private long initCntr;
-
+public interface PartitionUpdateCounter extends Iterable<long[]> {
/**
- * @param log Logger.
+ * Restores update counter state.
+ *
+ * @param initUpdCntr LWM.
+ * @param cntrUpdData Counter updates raw data.
*/
- PartitionUpdateCounter(IgniteLogger log) {
- this.log = log;
- }
+ public void init(long initUpdCntr, @Nullable byte[] cntrUpdData);
/**
- * Sets init counter.
- *
- * @param updateCntr Init counter valus.
+ * @deprecated TODO LWM should be used as initial counter https://ggsystems.atlassian.net/browse/GG-17396
*/
- public void init(long updateCntr) {
- initCntr = updateCntr;
+ public long initial();
- cntr.set(updateCntr);
- }
+ /**
+ * Get LWM.
+ */
+ public long get();
/**
- * @return Initial counter value.
+ * Increment LWM by 1.
+ *
+ * @return New LWM.
*/
- public long initial() {
- return initCntr;
- }
+ public long next();
/**
- * @return Current update counter value.
+ * Increment LWM by delta.
+ *
+ * @param delta Delta.
*/
- public long get() {
- return cntr.get();
- }
+ public long next(long delta);
/**
- * Adds delta to current counter value.
+ * Increment HWM by delta.
*
* @param delta Delta.
- * @return Value before add.
+ * @return New HWM.
*/
- public long getAndAdd(long delta) {
- return cntr.getAndAdd(delta);
- }
+ public long reserve(long delta);
/**
- * @return Next update counter.
+ * Returns HWM.
*/
- public long next() {
- return cntr.incrementAndGet();
- }
+ public long reserved();
/**
- * Sets value to update counter,
+ * Sets update counter to absolute value. All missed updates will be discarded.
*
- * @param val Values.
+ * @param val Absolute value.
+ * @throws IgniteCheckedException if counter cannot be set to passed value due to incompatibility with current state.
*/
- public void update(long val) {
- while (true) {
- long val0 = cntr.get();
-
- if (val0 >= val)
- break;
-
- if (cntr.compareAndSet(val0, val))
- break;
- }
- }
+ public void update(long val) throws IgniteCheckedException;
/**
- * Updates counter by delta from start position.
+ * Applies counter update out of range. Update ranges must not intersect.
*
- * @param start Start.
+ * @param start Start (<= lwm).
* @param delta Delta.
+ * @return {@code True} if update was actually applied.
*/
- public synchronized void update(long start, long delta) {
- long cur = cntr.get(), next;
-
- if (cur > start) {
- log.warning("Stale update counter task [cur=" + cur + ", start=" + start + ", delta=" + delta + ']');
-
- return;
- }
-
- if (cur < start) {
- // backup node with gaps
- offer(new Item(start, delta));
-
- return;
- }
-
- while (true) {
- boolean res = cntr.compareAndSet(cur, next = start + delta);
-
- assert res;
-
- Item peek = peek();
-
- if (peek == null || peek.start != next)
- return;
-
- Item item = poll();
-
- assert peek == item;
-
- start = item.start;
- delta = item.delta;
- cur = next;
- }
- }
+ public boolean update(long start, long delta);
/**
- * @param cntr Sets initial counter.
+ * Reset counter internal state to zero.
*/
- public void updateInitial(long cntr) {
- if (get() < cntr)
- update(cntr);
-
- initCntr = cntr;
- }
+ public void reset();
/**
- * @return Retrieves the minimum update counter task from queue.
+ * @param start Counter.
+ * @param delta Delta.
+ * @deprecated TODO https://ggsystems.atlassian.net/browse/GG-17396
*/
- private Item poll() {
- return queue.pollFirst();
- }
+ public void updateInitial(long start, long delta);
/**
- * @return Checks the minimum update counter task from queue.
+ * Flushes pending update counters closing all possible gaps.
+ *
+ * @return Even-length array of pairs [start, end] for each gap.
*/
- private Item peek() {
- return queue.isEmpty() ? null : queue.first();
+ public GridLongList finalizeUpdateCounters();
- }
+ /** */
+ public @Nullable byte[] getBytes();
/**
- * @param item Adds update task to priority queue.
+ * @return {@code True} if counter has no missed updates.
*/
- private void offer(Item item) {
- queue.add(item);
- }
+ public boolean sequential();
/**
- * Flushes pending update counters closing all possible gaps.
- *
- * @return Even-length array of pairs [start, end] for each gap.
+ * @return {@code True} if counter has not seen any update.
*/
- public synchronized GridLongList finalizeUpdateCounters() {
- Item item = poll();
-
- GridLongList gaps = null;
-
- while (item != null) {
- if (gaps == null)
- gaps = new GridLongList((queue.size() + 1) * 2);
-
- long start = cntr.get() + 1;
- long end = item.start;
-
- gaps.add(start);
- gaps.add(end);
-
- // Close pending ranges.
- update(item.start + item.delta);
-
- item = poll();
- }
-
- return gaps;
- }
+ public boolean empty();
/**
- * Update counter task. Update from start value by delta value.
+ * @return Iterator for pairs [start, delta] for each out-of-order update in the update counter sequence.
*/
- private static class Item implements Comparable<Item> {
- /** */
- private final long start;
-
- /** */
- private final long delta;
-
- /**
- * @param start Start value.
- * @param delta Delta value.
- */
- private Item(long start, long delta) {
- this.start = start;
- this.delta = delta;
- }
-
- /** {@inheritDoc} */
- @Override public int compareTo(@NotNull Item o) {
- return Long.compare(this.start, o.start);
- }
- }
+ @Override public Iterator<long[]> iterator();
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java
index 9d962db..335caf3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java
@@ -417,7 +417,7 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
if (hasNonEmptyOwning)
break;
- if (locPart.updateCounter() > 0) {
+ if (!locPart.isEmpty()) {
hasNonEmptyOwning = true;
break;
@@ -435,9 +435,8 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
", grpId=" + grp.groupId() + ", hasOwning=" + hasOwning + ", hasMoving=" + hasMoving +
", WALState=" + grp.walEnabled() + ", parts=" + parts);
- if (hasOwning && !grp.localWalEnabled()) {
+ if (hasOwning && !grp.localWalEnabled())
grpsToEnableWal.add(grp.groupId());
- }
else if (hasMoving && !hasOwning && grp.localWalEnabled()) {
grpsToDisableWal.add(grp.groupId());
@@ -498,10 +497,13 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
tmpDisabledWal = null;
}
+ // Pending updates in groups with disabled WAL are not protected from crash.
+ // Need to trigger checkpoint for attempt to persist them.
CheckpointFuture cpFut = triggerCheckpoint("wal-local-state-changed-rebalance-finished-" + topVer);
assert cpFut != null;
+ // It's safe to switch partitions to owning state only if checkpoint was successfully finished.
cpFut.finishFuture().listen(new IgniteInClosureX<IgniteInternalFuture>() {
@Override public void applyx(IgniteInternalFuture future) {
for (Integer grpId0 : session0.disabledGrps) {
@@ -511,12 +513,12 @@ public class WalStateManager extends GridCacheSharedManagerAdapter {
grp.topology().ownMoving(topVer);
else if (log.isDebugEnabled())
log.debug("Cache group was destroyed before checkpoint finished, [grpId=" + grpId0 + ']');
-
}
if (log.isDebugEnabled())
log.debug("Refresh partitions due to rebalance finished");
+ // Trigger exchange for switching to ideal assignment when all nodes are ready.
cctx.exchange().refreshPartitions();
}
});
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index 3e68306..22e3dd5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -915,12 +915,11 @@ public abstract class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
TxCounters counters = txCounters(false);
if (counters != null)
- cctx.tm().txHandler().applyPartitionsUpdatesCounters(counters.updateCounters());
+ cctx.tm().txHandler().applyPartitionsUpdatesCounters(counters.updateCounters(), true, false);
state(ROLLED_BACK);
cctx.mvccCaching().onTxFinished(this, false);
-
}
}
catch (IgniteCheckedException | RuntimeException | Error e) {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
index a1eb01c..584ede2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteClosure;
@@ -98,8 +99,33 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
/** {@inheritDoc} */
@Override protected long nextPartitionCounter(AffinityTopologyVersion topVer,
boolean primary,
+ boolean init,
@Nullable Long primaryCntr) {
- return locPart.nextUpdateCounter(cctx.cacheId(), topVer, primary, primaryCntr);
+ try {
+ return locPart.nextUpdateCounter(cctx.cacheId(), topVer, primary, init, primaryCntr);
+ }
+ catch (Throwable t) {
+ log.error("Failed to update counter for atomic cache [" +
+ ", initial=" + init +
+ ", primaryCntr=" + primaryCntr +
+ ", part=" + locPart + ']', t);
+
+ throw t;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected long nextPartitionCounter(IgniteInternalTx tx, @Nullable Long primaryCntr) {
+ try {
+ return locPart.nextUpdateCounter(cctx.cacheId(), tx, primaryCntr);
+ }
+ catch (Throwable t) {
+ log.error("Failed to update counter for tx cache [" +
+ ", primaryCntr=" + primaryCntr +
+ ", part=" + locPart + ", tx=" + CU.txString(tx) + ']', t);
+
+ throw t;
+ }
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
index b00ad56..dc29ebe 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
@@ -38,7 +37,6 @@ import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTx
import org.apache.ignite.internal.processors.cache.mvcc.MvccFuture;
import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
-import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -437,11 +435,6 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCacheCompoundIdentity
add(fut); // Append new future.
- Collection<Long> updCntrs = new ArrayList<>(dhtMapping.entries().size());
-
- for (IgniteTxEntry e : dhtMapping.entries())
- updCntrs.add(e.updateCounter());
-
GridDhtTxFinishRequest req = new GridDhtTxFinishRequest(
tx.nearNodeId(),
futId,
@@ -465,7 +458,7 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCacheCompoundIdentity
tx.subjectId(),
tx.taskNameHash(),
tx.activeCachesDeploymentEnabled(),
- updCntrs,
+ null,
false,
false,
mvccSnapshot,
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
index 04f411d..9498e32 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
@@ -257,13 +257,6 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
waitRemoteTxs,
mvccSnapshot,
updCntrs);
-
- if (updateIdxs != null && !updateIdxs.isEmpty()) {
- partUpdateCnt = new GridLongList(updateIdxs.size());
-
- for (Long idx : updateIdxs)
- partUpdateCnt.add(idx);
- }
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index fb485a5..83edb29 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -71,6 +71,7 @@ import org.apache.ignite.internal.processors.cache.mvcc.txlog.TxState;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.transactions.TxCounters;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.dr.GridDrType;
import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter;
@@ -1258,6 +1259,8 @@ public final class GridDhtTxPrepareFuture extends GridCacheCompoundFuture<Ignite
*
*/
private void prepare0() {
+ boolean error = false;
+
try {
if (tx.serializable() && tx.optimistic()) {
IgniteCheckedException err0;
@@ -1297,10 +1300,24 @@ public final class GridDhtTxPrepareFuture extends GridCacheCompoundFuture<Ignite
// We are holding transaction-level locks for entries here, so we can get next write version.
tx.writeVersion(cctx.versions().next(tx.topologyVersion()));
+ TxCounters counters = tx.txCounters(true);
+
// Assign keys to primary nodes.
if (!F.isEmpty(req.writes())) {
- for (IgniteTxEntry write : req.writes())
- map(tx.entry(write.txKey()));
+ for (IgniteTxEntry write : req.writes()) {
+ IgniteTxEntry entry = tx.entry(write.txKey());
+
+ assert entry != null && entry.cached() != null : entry;
+
+ // Counter shouldn't be reserved for mvcc, local cache entries, NOOP operations and NOOP transforms.
+ if (!entry.cached().isLocal() && entry.op() != NOOP &&
+ !(entry.op() == TRANSFORM &&
+ (entry.entryProcessorCalculatedValue() == null || // Possible for txs over cachestore
+ entry.entryProcessorCalculatedValue().get1() == NOOP)))
+ counters.incrementUpdateCounter(entry.cacheId(), entry.cached().partition());
+
+ map(entry);
+ }
}
if (!F.isEmpty(req.reads())) {
@@ -1312,6 +1329,12 @@ public final class GridDhtTxPrepareFuture extends GridCacheCompoundFuture<Ignite
return;
if (last) {
+ if (!tx.txState().mvccEnabled()) {
+ /** For MVCC counters are assigned on enlisting. */
+ /** See usage of {@link TxCounters#incrementUpdateCounter(int, int)} ) */
+ tx.calculatePartitionUpdateCounters();
+ }
+
recheckOnePhaseCommit();
if (tx.onePhaseCommit())
@@ -1320,8 +1343,14 @@ public final class GridDhtTxPrepareFuture extends GridCacheCompoundFuture<Ignite
sendPrepareRequests();
}
}
+ catch (Throwable t) {
+ error = true;
+
+ throw t;
+ }
finally {
- markInitialized();
+ if (!error) // Prevent marking future as initialized on error.
+ markInitialized();
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/PartitionUpdateCountersMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/PartitionUpdateCountersMessage.java
index f30d51d..ba7b590 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/PartitionUpdateCountersMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/PartitionUpdateCountersMessage.java
@@ -19,9 +19,11 @@ package org.apache.ignite.internal.processors.cache.distributed.dht;
import java.nio.ByteBuffer;
import java.util.Arrays;
+import java.util.Map;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.IgniteCodeGeneratingFail;
import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
import org.apache.ignite.plugin.extensions.communication.MessageWriter;
@@ -47,6 +49,10 @@ public class PartitionUpdateCountersMessage implements Message {
@GridDirectTransient
private int size;
+ /** Used for assigning counters to cache entries during tx finish. */
+ @GridDirectTransient
+ private Map<Integer, Long> counters;
+
/** */
public PartitionUpdateCountersMessage() {
// No-op.
@@ -145,6 +151,24 @@ public class PartitionUpdateCountersMessage implements Message {
}
/**
+ * Calculate next counter for partition.
+ *
+ * @param partId Partition id.
+ *
+ * @return Next counter for partition.
+ */
+ public Long nextCounter(int partId) {
+ if (counters == null) {
+ counters = U.newHashMap(size);
+
+ for (int i = 0; i < size; i++)
+ counters.put(partition(i), initialCounter(i));
+ }
+
+ return counters.computeIfPresent(partId, (key, cntr) -> cntr + 1);
+ }
+
+ /**
* Clears message.
*/
public void clear() {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
index 93602db..803681f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
@@ -1025,8 +1025,10 @@ public class GridDhtPartitionDemander {
try {
cached = cctx.cache().entryEx(entry.key(), topVer);
- if (log.isTraceEnabled())
- log.trace("Rebalancing key [key=" + entry.key() + ", part=" + p + ", node=" + from.id() + ']');
+ if (log.isTraceEnabled()) {
+ log.trace("Rebalancing key [key=" + entry.key() + ", part=" + p + ", fromNode=" +
+ from.id() + ", grpId=" + grp.groupId() + ']');
+ }
if (preloadPred == null || preloadPred.apply(entry)) {
if (cached.initialValue(
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
index 7f52856..a216a16 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
@@ -445,6 +445,15 @@ class GridDhtPartitionSupplier {
log.info("Finished supplying rebalancing [" + supplyRoutineInfo(topicId, nodeId, demandMsg) + "]");
}
catch (Throwable t) {
+ if (iter != null && !iter.isClosed()) {
+ try {
+ iter.close();
+ }
+ catch (IgniteCheckedException e) {
+ t.addSuppressed(e);
+ }
+ }
+
if (grp.shared().kernalContext().isStopping())
return;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 0ec1b7c..b247cd2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -297,7 +297,7 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
@GridToStringExclude
private volatile IgniteDhtPartitionHistorySuppliersMap partHistSuppliers = new IgniteDhtPartitionHistorySuppliersMap();
- /** */
+ /** Reserved max available history for calculation of history supplier on coordinator. */
private volatile Map<Integer, Map<Integer, Long>> partHistReserved;
/** */
@@ -354,6 +354,9 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
/** Discovery lag / Clocks discrepancy, calculated on coordinator when all single messages are received. */
private T2<Long, UUID> discoveryLag;
+ /** TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11799 */
+ private Map<Integer, Set<Integer>> clearingPartitions;
+
/**
* @param cctx Cache context.
* @param busyLock Busy lock.
@@ -1053,6 +1056,7 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
clientTop.fullUpdateCounters(),
Collections.emptySet(),
null,
+ null,
null);
}
finally {
@@ -1436,6 +1440,8 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
cctx.exchange().exchangerBlockingSectionEnd();
}
+ clearingPartitions = new HashMap();
+
timeBag.finishGlobalStage("WAL history reservation");
// Skipping wait on local join is available when all cluster nodes have the same protocol.
@@ -1674,7 +1680,7 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
cctx.exchange().exchangerBlockingSectionBegin();
try {
- // This avoids unnessesary waiting for rollback.
+ // This avoids unnecessary waiting for rollback.
partReleaseFut.get(curTimeout > 0 && !txRolledBack ?
Math.min(curTimeout, waitTimeout) : waitTimeout, TimeUnit.MILLISECONDS);
@@ -3119,10 +3125,10 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
continue;
if (localReserved != null) {
- Long localCntr = localReserved.get(p);
+ Long localHistCntr = localReserved.get(p);
- if (localCntr != null && localCntr <= minCntr && maxCntrObj.nodes.contains(cctx.localNodeId())) {
- partHistSuppliers.put(cctx.localNodeId(), top.groupId(), p, localCntr);
+ if (localHistCntr != null && localHistCntr <= minCntr && maxCntrObj.nodes.contains(cctx.localNodeId())) {
+ partHistSuppliers.put(cctx.localNodeId(), top.groupId(), p, localHistCntr);
haveHistory.add(p);
@@ -3153,7 +3159,7 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
top.globalPartSizes(partSizes);
- Map<UUID, Set<Integer>> partitionsToRebalance = top.resetOwners(ownersByUpdCounters, haveHistory);
+ Map<UUID, Set<Integer>> partitionsToRebalance = top.resetOwners(ownersByUpdCounters, haveHistory, this);
for (Map.Entry<UUID, Set<Integer>> e : partitionsToRebalance.entrySet()) {
UUID nodeId = e.getKey();
@@ -3457,13 +3463,8 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
&& ((SnapshotDiscoveryMessage)discoveryCustomMessage).needAssignPartitions())
assignPartitionsStates();
}
- else {
- if (exchCtx.events().hasServerJoin())
- assignPartitionsStates();
-
- if (exchCtx.events().hasServerLeft())
- detectLostPartitions(resTopVer);
- }
+ else if (exchCtx.events().hasServerJoin())
+ assignPartitionsStates();
// Recalculate new affinity based on partitions availability.
if (!exchCtx.mergeExchanges() && forceAffReassignment) {
@@ -3488,6 +3489,12 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
GridDhtPartitionsFullMessage msg = createPartitionsMessage(true,
minVer.compareToIgnoreTimestamp(PARTIAL_COUNTERS_MAP_SINCE) >= 0);
+ // Lost partition detection should be done after full message is prepared otherwise in case of IGNORE policy
+ // lost partitions will be moved to OWNING state and after what send to other nodes resulting in
+ // wrong lost state calculation (another possibility to consider - calculate lost state only on coordinator).
+ if (firstDiscoEvt.type() != EVT_DISCOVERY_CUSTOM_EVT && exchCtx.events().hasServerLeft())
+ detectLostPartitions(resTopVer);
+
if (exchCtx.mergeExchanges()) {
assert !centralizedAff;
@@ -3776,7 +3783,7 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
int parallelismLvl = U.availableThreadCount(cctx.kernalContext(), GridIoPolicy.SYSTEM_POOL, 2);
try {
- U.<CacheGroupContext, Void>doInParallel(
+ U.<CacheGroupContext, Void>doInParallelUninterruptibly(
parallelismLvl,
cctx.kernalContext().getSystemExecutorService(),
nonLocalCacheGroups(),
@@ -4220,7 +4227,8 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
cntrMap,
msg.partsToReload(cctx.localNodeId(), grpId),
partsSizes.getOrDefault(grpId, Collections.emptyMap()),
- null);
+ null,
+ this);
}
else {
GridDhtPartitionTopology top = cctx.exchange().clientTopology(grpId, events().discoveryCache());
@@ -4233,7 +4241,8 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
cntrMap,
Collections.emptySet(),
null,
- null);
+ null,
+ this);
}
return null;
@@ -5018,6 +5027,40 @@ public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapte
}
/**
+ * If partition is clearing or already cleared we need full rebalance even if supplier is exists.
+ * (it still could be used by other demanders)
+ *
+ * @param grp Group.
+ * @param part Partition.
+ */
+ public boolean isClearingPartition(CacheGroupContext grp, int part) {
+ if (!grp.persistenceEnabled())
+ return false;
+
+ synchronized (mux) {
+ if (clearingPartitions == null)
+ return false;
+
+ Set<Integer> parts = clearingPartitions.get(grp.groupId());
+
+ return parts != null && parts.contains(part);
+ }
+ }
+
+ /**
+ * @param grp Group.
+ * @param part Partition.
+ */
+ public void addClearingPartition(CacheGroupContext grp, int part) {
+ if (!grp.persistenceEnabled())
+ return;
+
+ synchronized (mux) {
+ clearingPartitions.computeIfAbsent(grp.groupId(), k -> new HashSet()).add(part);
+ }
+ }
+
+ /**
*
*/
private static class FinishState {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
index ff420a7..8ecb147 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
@@ -253,6 +253,10 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
if (part.state() == RENTING) {
if (part.reserve()) {
part.moving();
+
+ if (exchFut != null)
+ exchFut.addClearingPartition(grp, part.id());
+
part.clearAsync();
part.release();
@@ -277,7 +281,8 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
histSupplier = ctx.discovery().node(nodeId);
}
- if (histSupplier != null) {
+ // Clearing partition should always be fully reloaded.
+ if (histSupplier != null && !exchFut.isClearingPartition(grp, p)) {
assert grp.persistenceEnabled();
assert remoteOwners(p, topVer).contains(histSupplier) : remoteOwners(p, topVer);
@@ -291,6 +296,7 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
);
}
+ // TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11790
msg.partitions().addHistorical(p, part.initialUpdateCounter(), countersMap.updateCounter(p), partitions);
}
else {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloaderAssignments.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloaderAssignments.java
index 6f98889..8783c73 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloaderAssignments.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloaderAssignments.java
@@ -81,7 +81,6 @@ public class GridDhtPreloaderAssignments extends ConcurrentHashMap<ClusterNode,
/** {@inheritDoc} */
@Override public String toString() {
- return S.toString(GridDhtPreloaderAssignments.class, this, "exchId", exchangeId,
- "super", super.toString());
+ return S.toString(GridDhtPreloaderAssignments.class, this, "super", super.toString());
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtDemandedPartitionsMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtDemandedPartitionsMap.java
index 9fe3c64..c1109b3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtDemandedPartitionsMap.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtDemandedPartitionsMap.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;
@@ -36,6 +37,7 @@ public class IgniteDhtDemandedPartitionsMap implements Serializable {
private CachePartitionPartialCountersMap historical;
/** Set of partitions that will be preloaded from all it's current data. */
+ @GridToStringInclude
private Set<Integer> full;
public IgniteDhtDemandedPartitionsMap(
@@ -47,6 +49,7 @@ public class IgniteDhtDemandedPartitionsMap implements Serializable {
}
public IgniteDhtDemandedPartitionsMap() {
+ // No-op.
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridClientPartitionTopology.java
index 0298d31..8a8d7d0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridClientPartitionTopology.java
@@ -729,7 +729,8 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
@Nullable CachePartitionFullCountersMap cntrMap,
Set<Integer> partsToReload,
@Nullable Map<Integer, Long> partSizes,
- @Nullable AffinityTopologyVersion msgTopVer) {
+ @Nullable AffinityTopologyVersion msgTopVer,
+ @Nullable GridDhtPartitionsExchangeFuture exchFut) {
if (log.isDebugEnabled())
log.debug("Updating full partition map [exchVer=" + exchangeVer + ", parts=" + fullMapString() + ']');
@@ -1162,7 +1163,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
}
/** {@inheritDoc} */
- @Override public Map<UUID, Set<Integer>> resetOwners(Map<Integer, Set<UUID>> ownersByUpdCounters, Set<Integer> haveHistory) {
+ @Override public Map<UUID, Set<Integer>> resetOwners(Map<Integer, Set<UUID>> ownersByUpdCounters,
+ Set<Integer> haveHistory,
+ GridDhtPartitionsExchangeFuture exchFut) {
Map<UUID, Set<Integer>> result = new HashMap<>();
lock.writeLock().lock();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtLocalPartition.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtLocalPartition.java
index c1f742e..a131a21 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtLocalPartition.java
@@ -53,12 +53,15 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservabl
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.processors.cache.transactions.TxCounters;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.query.GridQueryRowCacheCleaner;
import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.GridIterator;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.typedef.internal.LT;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteInClosure;
@@ -218,7 +221,7 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
// Log partition creation for further crash recovery purposes.
if (grp.walEnabled() && !recovery)
- ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, state(), updateCounter()));
+ ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, state(), 0));
// Inject row cache cleaner on store creation
// Used in case the cache with enabled SqlOnheapCache is single cache at the cache group
@@ -396,9 +399,21 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
}
/**
- *
+ * TODO FIXME Get rid of deferred delete queue https://issues.apache.org/jira/browse/IGNITE-11704
*/
public void cleanupRemoveQueue() {
+ if (state() == MOVING) {
+ if (rmvQueue.sizex() >= rmvQueueMaxSize) {
+ LT.warn(log, "Deletion queue cleanup for moving partition was delayed until rebalance is finished. " +
+ "[grpId=" + this.grp.groupId() +
+ ", partId=" + id() +
+ ", grpParts=" + this.grp.affinity().partitions() +
+ ", maxRmvQueueSize=" + rmvQueueMaxSize + ']');
+ }
+
+ return;
+ }
+
while (rmvQueue.sizex() >= rmvQueueMaxSize) {
RemovedEntryHolder item = rmvQueue.pollFirst();
@@ -535,7 +550,7 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
this.state.compareAndSet(state0, setPartState(state0, toState));
try {
- ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, toState, updateCounter()));
+ ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, toState, 0));
}
catch (IgniteCheckedException e) {
U.error(log, "Error while writing to log", e);
@@ -560,7 +575,7 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
if (update) {
try {
- ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, toState, updateCounter()));
+ ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, toState, 0));
}
catch (IgniteCheckedException e) {
U.error(log, "Failed to log partition state change to WAL.", e);
@@ -717,7 +732,7 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
}
}
- ctx.evict().evictPartitionAsync(grp,this);
+ ctx.evict().evictPartitionAsync(grp, this);
}
/**
@@ -970,40 +985,82 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
}
/**
+ * Returns new update counter for primary node or passed counter for backup node.
+ * <p>
+ * Used for non-tx cases.
+ * <p>
+ * Counter generation/update logic is delegated to counter implementation.
+ *
* @param cacheId ID of cache initiated counter update.
* @param topVer Topology version for current operation.
+ * @param init {@code True} if initial update.
* @return Next update index.
*/
- public long nextUpdateCounter(int cacheId, AffinityTopologyVersion topVer, boolean primary, @Nullable Long primaryCntr) {
- long nextCntr = store.nextUpdateCounter();
+ public long nextUpdateCounter(int cacheId, AffinityTopologyVersion topVer, boolean primary, boolean init,
+ @Nullable Long primaryCntr) {
+ long nextCntr;
+
+ if (primaryCntr == null) // Primary node.
+ nextCntr = store.nextUpdateCounter();
+ else {
+ assert !init : "Initial update must generate a counter for partition " + this;
+
+ // Backup.
+ assert primaryCntr != 0;
+
+ store.updateCounter(nextCntr = primaryCntr);
+ }
if (grp.sharedGroup())
- grp.onPartitionCounterUpdate(cacheId, id, primaryCntr != null ? primaryCntr : nextCntr, topVer, primary);
+ grp.onPartitionCounterUpdate(cacheId, id, nextCntr, topVer, primary);
- // This is first update in partition, we should log partition state information for further crash recovery.
- if (nextCntr == 1) {
- if (grp.persistenceEnabled() && grp.walEnabled())
- try {
- ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, state(), 0));
- }
- catch (IgniteCheckedException e) {
- U.error(log, "Failed to log partition state snapshot to WAL.", e);
+ return nextCntr;
+ }
- ctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
- }
+ /**
+ * Used for transactions.
+ *
+ * @param cacheId Cache id.
+ * @param tx Tx.
+ * @param primaryCntr Primary counter.
+ */
+ public long nextUpdateCounter(int cacheId, IgniteInternalTx tx, @Nullable Long primaryCntr) {
+ Long nextCntr;
+
+ if (primaryCntr != null)
+ nextCntr = primaryCntr;
+ else {
+ TxCounters txCounters = tx.txCounters(false);
+
+ assert txCounters != null : "Must have counters for tx [nearXidVer=" + tx.nearXidVersion() + ']';
+
+ // Null must never be returned on primary node.
+ nextCntr = txCounters.generateNextCounter(cacheId, id());
+
+ assert nextCntr != null : this;
}
+ if (grp.sharedGroup())
+ grp.onPartitionCounterUpdate(cacheId, id, nextCntr, tx.topologyVersion(), tx.local());
+
return nextCntr;
}
/**
- * @return Current update counter.
+ * @return Current update counter (LWM).
*/
public long updateCounter() {
return store.updateCounter();
}
/**
+ * @return Current reserved counter (HWM).
+ */
+ public long reservedCounter() {
+ return store.reservedCounter();
+ }
+
+ /**
* @param val Update counter value.
*/
public void updateCounter(long val) {
@@ -1018,14 +1075,7 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
}
/**
- * @param val Initial update counter value.
- */
- public void initialUpdateCounter(long val) {
- store.updateInitialCounter(val);
- }
-
- /**
- * Updates MVCC cache update counter on primary node.
+ * Increments cache update counter on primary node.
*
* @param delta Value to be added to update counter.
* @return Update counter value before update.
@@ -1040,8 +1090,15 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
* @param start Start position
* @param delta Delta.
*/
- public void updateCounter(long start, long delta) {
- store.updateCounter(start, delta);
+ public boolean updateCounter(long start, long delta) {
+ return store.updateCounter(start, delta);
+ }
+
+ /**
+ * Reset partition counters.
+ */
+ public void resetCounters() {
+ store.resetUpdateCounter();
}
/**
@@ -1086,7 +1143,8 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
try {
CacheDataRow row = it0.next();
- // Do not clear fresh rows in case of single partition clearing.
+ // Do not clear fresh rows in case of partition reloading.
+ // This is required because updates are possible to moving partition which is currently cleared.
if (row.version().compareTo(clearVer) >= 0 && (state() == MOVING && clear))
continue;
@@ -1256,7 +1314,8 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
"state", state(),
"reservations", reservations(),
"empty", isEmpty(),
- "createTime", U.format(createTime));
+ "createTime", U.format(createTime),
+ "cntr", dataStore().partUpdateCounter());
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopology.java
index 7b9c3c3..f907bf2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopology.java
@@ -292,6 +292,7 @@ public interface GridDhtPartitionTopology {
* @param partsToReload Set of partitions that need to be reloaded.
* @param msgTopVer Topology version from incoming message. This value is not null only for case message is not
* related to exchange. Value should be not less than previous 'Topology version from exchange'.
+ * @param exchFut Future which is not null for initial partition update on exchange.
* @return {@code True} if local state was changed.
*/
public boolean update(
@@ -300,7 +301,9 @@ public interface GridDhtPartitionTopology {
@Nullable CachePartitionFullCountersMap cntrMap,
Set<Integer> partsToReload,
@Nullable Map<Integer, Long> partSizes,
- @Nullable AffinityTopologyVersion msgTopVer);
+ @Nullable AffinityTopologyVersion msgTopVer,
+ @Nullable GridDhtPartitionsExchangeFuture exchFut
+ );
/**
* @param exchId Exchange ID.
@@ -359,7 +362,7 @@ public interface GridDhtPartitionTopology {
public CachePartitionFullCountersMap fullUpdateCounters();
/**
- * @param skipZeros {@code True} for adding zero counter to map.
+ * @param skipZeros {@code True} to exclude zero counters from map.
* @return Partition update counters.
*/
public CachePartitionPartialCountersMap localUpdateCounters(boolean skipZeros);
@@ -420,13 +423,16 @@ public interface GridDhtPartitionTopology {
/**
* Calculates nodes and partitions which have non-actual state and must be rebalanced.
* State of all current owners that aren't contained in the given {@code ownersByUpdCounters} will be reset to MOVING.
+ * Called on coordinator during assignment of partition states.
*
* @param ownersByUpdCounters Map (partition, set of node IDs that have most actual state about partition
* (update counter is maximal) and should hold OWNING state for such partition).
* @param haveHistory Set of partitions which have WAL history to rebalance.
+ * @param exchFut Exchange future for operation.
* @return Map (nodeId, set of partitions that should be rebalanced <b>fully</b> by this node).
*/
- public Map<UUID, Set<Integer>> resetOwners(Map<Integer, Set<UUID>> ownersByUpdCounters, Set<Integer> haveHistory);
+ public Map<UUID, Set<Integer>> resetOwners(Map<Integer, Set<UUID>> ownersByUpdCounters, Set<Integer> haveHistory,
+ GridDhtPartitionsExchangeFuture exchFut);
/**
* Callback on exchange done.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopologyImpl.java
index 026a54f..b6b84d5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/GridDhtPartitionTopologyImpl.java
@@ -42,6 +42,7 @@ import org.apache.ignite.events.EventType;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.IgniteInterruptedCheckedException;
import org.apache.ignite.internal.managers.discovery.DiscoCache;
+import org.apache.ignite.internal.pagemem.wal.record.RollbackRecord;
import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheGroupContext;
@@ -428,7 +429,7 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
}
}
else
- createPartitions(affVer, affAssignment, updateSeq);
+ createPartitions(affVer, affAssignment, updateSeq, exchFut);
}
else {
// If preloader is disabled, then we simply clear out
@@ -478,8 +479,10 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
* @param affVer Affinity version.
* @param aff Affinity assignments.
* @param updateSeq Update sequence.
+ * @param exchFut
*/
- private void createPartitions(AffinityTopologyVersion affVer, List<List<ClusterNode>> aff, long updateSeq) {
+ private void createPartitions(AffinityTopologyVersion affVer, List<List<ClusterNode>> aff, long updateSeq,
+ GridDhtPartitionsExchangeFuture exchFut) {
if (!grp.affinityNode())
return;
@@ -493,8 +496,13 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (localNode(p, aff)) {
// This will make sure that all non-existing partitions
// will be created in MOVING state.
+ boolean existing = locParts.get(p) != null;
+
GridDhtLocalPartition locPart = getOrCreatePartition(p);
+ if (existing && locPart.state() == MOVING && !locPart.isEmpty())
+ exchFut.addClearingPartition(grp, p);
+
updateSeq = updateLocal(p, locPart.state(), updateSeq, affVer);
}
}
@@ -758,7 +766,7 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (partitionLocalNode(p, topVer)) {
// Prepare partition to rebalance if it's not happened on full map update phase.
if (locPart == null || locPart.state() == RENTING || locPart.state() == EVICTED)
- locPart = rebalancePartition(p, false);
+ locPart = rebalancePartition(p, true, exchFut);
GridDhtPartitionState state = locPart.state();
@@ -772,6 +780,9 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
log.debug("Will not own partition (there are owners to rebalance from) " +
"[grp=" + grp.cacheOrGroupName() + ", p=" + p + ", owners = " + owners + ']');
}
+
+ if (exchFut.isClearingPartition(grp, p))
+ locPart.clearAsync();
}
else
updateSeq = updateLocal(p, locPart.state(), updateSeq, topVer);
@@ -1359,8 +1370,9 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
*/
private boolean shouldOverridePartitionMap(GridDhtPartitionMap currentMap, GridDhtPartitionMap newMap) {
return newMap != null &&
- (newMap.topologyVersion().compareTo(currentMap.topologyVersion()) > 0 ||
- newMap.topologyVersion().compareTo(currentMap.topologyVersion()) == 0 && newMap.updateSequence() > currentMap.updateSequence());
+ (newMap.topologyVersion().compareTo(currentMap.topologyVersion()) > 0 ||
+ newMap.topologyVersion().compareTo(currentMap.topologyVersion()) == 0 &&
+ newMap.updateSequence() > currentMap.updateSequence());
}
/** {@inheritDoc} */
@@ -1370,7 +1382,8 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
@Nullable CachePartitionFullCountersMap incomeCntrMap,
Set<Integer> partsToReload,
@Nullable Map<Integer, Long> partSizes,
- @Nullable AffinityTopologyVersion msgTopVer) {
+ @Nullable AffinityTopologyVersion msgTopVer,
+ @Nullable GridDhtPartitionsExchangeFuture exchFut) {
if (log.isDebugEnabled()) {
log.debug("Updating full partition map " +
"[grp=" + grp.cacheOrGroupName() + ", exchVer=" + exchangeVer + ", fullMap=" + fullMapString() + ']');
@@ -1408,17 +1421,21 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
long updCntr = incomeCntrMap.updateCounter(part.id());
long curCntr = part.updateCounter();
- if (updCntr != 0 && updCntr > curCntr) {
+ // Avoid zero counter update to empty partition to prevent lazy init.
+ if (updCntr != 0 || curCntr != 0) {
part.updateCounter(updCntr);
- if (log.isDebugEnabled())
- log.debug("Partition update counter has updated [grp=" + grp.cacheOrGroupName() + ", p=" + part.id()
- + ", state=" + part.state() + ", prevCntr=" + curCntr + ", nextCntr=" + updCntr + "]");
+ if (updCntr > curCntr) {
+ if (log.isDebugEnabled())
+ log.debug("Partition update counter has updated [grp=" + grp.cacheOrGroupName() + ", p=" + part.id()
+ + ", state=" + part.state() + ", prevCntr=" + curCntr + ", nextCntr=" + updCntr + "]");
+ }
}
}
}
}
+ // TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11800
if (exchangeVer != null) {
// Ignore if exchange already finished or new exchange started.
if (readyTopVer.compareTo(exchangeVer) > 0 || lastTopChangeVer.compareTo(exchangeVer) > 0) {
@@ -1557,6 +1574,9 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
nodeMap != null &&
grp.persistenceEnabled() &&
readyTopVer.initialized()) {
+
+ assert exchFut != null;
+
for (Map.Entry<Integer, GridDhtPartitionState> e : nodeMap.entrySet()) {
int p = e.getKey();
GridDhtPartitionState state = e.getValue();
@@ -1575,9 +1595,7 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
}
}
else if (state == MOVING) {
- boolean haveHistory = !partsToReload.contains(p);
-
- rebalancePartition(p, haveHistory);
+ rebalancePartition(p, partsToReload.contains(p), exchFut);
changed = true;
}
@@ -1698,12 +1716,21 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
continue;
long updCntr = cntrMap.updateCounter(part.id());
+ long locUpdCntr = part.updateCounter();
- if (updCntr > part.updateCounter())
+ if (updCntr != 0 || locUpdCntr != 0) { // Avoid creation of empty partition.
part.updateCounter(updCntr);
- else if (part.updateCounter() > 0) {
+
+ if (updCntr > locUpdCntr) {
+ if (log.isDebugEnabled())
+ log.debug("Partition update counter has updated [grp=" + grp.cacheOrGroupName() + ", p=" + part.id()
+ + ", state=" + part.state() + ", prevCntr=" + locUpdCntr + ", nextCntr=" + updCntr + "]");
+ }
+ }
+
+ if (locUpdCntr > updCntr) {
cntrMap.initialUpdateCounter(part.id(), part.initialUpdateCounter());
- cntrMap.updateCounter(part.id(), part.updateCounter());
+ cntrMap.updateCounter(part.id(), locUpdCntr);
}
}
finally {
@@ -2105,7 +2132,7 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (recentlyLost != null) {
U.warn(log, "Detected lost partitions [grp=" + grp.cacheOrGroupName()
+ ", parts=" + S.compact(recentlyLost)
- + ", plc=" + plc + "]");
+ + ", plc=" + plc + ", topVer=" + resTopVer + "]");
}
if (lostParts != null && plc != PartitionLossPolicy.IGNORE)
@@ -2147,11 +2174,8 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (marked) {
updateLocal(locPart.id(), locPart.state(), updSeq, resTopVer);
- long updateCntr = locPart.updateCounter();
-
- //Set update counters to 0, for full rebalance.
- locPart.updateCounter(updateCntr, -updateCntr);
- locPart.initialUpdateCounter(0);
+ // Reset counters to zero for triggering full rebalance.
+ locPart.resetCounters();
}
}
}
@@ -2188,7 +2212,9 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
}
/** {@inheritDoc} */
- @Override public Map<UUID, Set<Integer>> resetOwners(Map<Integer, Set<UUID>> ownersByUpdCounters, Set<Integer> haveHistory) {
+ @Override public Map<UUID, Set<Integer>> resetOwners(Map<Integer, Set<UUID>> ownersByUpdCounters,
+ Set<Integer> haveHistory,
+ GridDhtPartitionsExchangeFuture exchFut) {
Map<UUID, Set<Integer>> result = new HashMap<>();
ctx.database().checkpointReadLock();
@@ -2208,10 +2234,9 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
continue;
if (!newOwners.contains(ctx.localNodeId())) {
- rebalancePartition(part, haveHistory.contains(part));
+ rebalancePartition(part, !haveHistory.contains(part), exchFut);
- result.computeIfAbsent(ctx.localNodeId(), n -> new HashSet<>());
- result.get(ctx.localNodeId()).add(part);
+ result.computeIfAbsent(ctx.localNodeId(), n -> new HashSet<>()).add(part);
}
}
@@ -2237,8 +2262,7 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (partMap.nodeId().equals(ctx.localNodeId()))
updateSeq.setIfGreater(partMap.updateSequence());
- result.computeIfAbsent(remoteNodeId, n -> new HashSet<>());
- result.get(remoteNodeId).add(part);
+ result.computeIfAbsent(remoteNodeId, n -> new HashSet<>()).add(part);
}
}
}
@@ -2247,6 +2271,10 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
UUID nodeId = entry.getKey();
Set<Integer> rebalancedParts = entry.getValue();
+ // Add to wait groups to ensure late assignment switch after all partitions are rebalanced.
+ for (Integer part : rebalancedParts)
+ ctx.cache().context().affinity().addToWaitGroup(groupId(), part, nodeId, topologyVersionFuture().initialVersion());
+
if (!rebalancedParts.isEmpty()) {
Set<Integer> historical = rebalancedParts.stream()
.filter(haveHistory::contains)
@@ -2281,10 +2309,11 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
* Prevents ongoing renting if required.
*
* @param p Partition id.
- * @param haveHistory If {@code true} there is WAL history to rebalance partition,
- * in other case partition will be cleared for full rebalance.
+ * @param clear If {@code true} partition have to be cleared before rebalance.
+ * Required in case of full state transfer to handle removals on supplier.
+ * @param exchFut Future related to partition state change.
*/
- private GridDhtLocalPartition rebalancePartition(int p, boolean haveHistory) {
+ private GridDhtLocalPartition rebalancePartition(int p, boolean clear, GridDhtPartitionsExchangeFuture exchFut) {
GridDhtLocalPartition part = getOrCreatePartition(p);
// Prevent renting.
@@ -2303,8 +2332,11 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
if (part.state() != MOVING)
part.moving();
- if (!haveHistory)
+ if (clear) {
+ exchFut.addClearingPartition(grp, part.id());
+
part.clearAsync();
+ }
assert part.state() == MOVING : part;
@@ -2656,9 +2688,6 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
* Pre-processes partition update counters before exchange.
*/
@Override public void finalizeUpdateCounters() {
- if (!grp.mvccEnabled())
- return;
-
// It is need to acquire checkpoint lock before topology lock acquiring.
ctx.database().checkpointReadLock();
@@ -2680,6 +2709,25 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
GridLongList gaps = part.finalizeUpdateCounters();
if (gaps != null) {
+ for (int j = 0; j < gaps.size() / 2; j++) {
+ long gapStart = gaps.get(j * 2);
+ long gapStop = gaps.get(j * 2 + 1);
+
+ if (part.group().persistenceEnabled() &&
+ part.group().walEnabled() &&
+ !part.group().mvccEnabled()) {
+ RollbackRecord rec = new RollbackRecord(part.group().groupId(), part.id(),
+ gapStart - 1, gapStop - gapStart + 1);
+
+ try {
+ ctx.wal().log(rec);
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+ }
+
for (GridCacheContext ctx0 : grp.caches())
ctx0.continuousQueries().closeBackupUpdateCountersGaps(ctx0, part.id(), topVer, gaps);
}
@@ -2964,7 +3012,7 @@ public class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
* Checks consistency after all operations.
*/
private void consistencyCheck() {
- // no-op
+ // No-op.
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/PartitionsEvictManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/PartitionsEvictManager.java
index 404e194..c458d3e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/PartitionsEvictManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/topology/PartitionsEvictManager.java
@@ -70,7 +70,7 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
private volatile boolean stop;
/** Check stop eviction context. */
- private final EvictionContext sharedEvictionContext = () -> stop;
+ private final EvictionContext sharedEvictionCtx = () -> stop;
/** Number of maximum concurrent operations. */
private volatile int threads;
@@ -94,13 +94,13 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
*
* @param grp Group context.
*/
- public void onCacheGroupStopped(CacheGroupContext grp){
- GroupEvictionContext groupEvictionContext = evictionGroupsMap.remove(grp.groupId());
+ public void onCacheGroupStopped(CacheGroupContext grp){
+ GroupEvictionContext grpEvictionCtx = evictionGroupsMap.remove(grp.groupId());
- if (groupEvictionContext != null){
- groupEvictionContext.stop();
+ if (grpEvictionCtx != null){
+ grpEvictionCtx.stop();
- groupEvictionContext.awaitFinishAll();
+ grpEvictionCtx.awaitFinishAll();
}
}
@@ -111,23 +111,23 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
* @param part Partition to evict.
*/
public void evictPartitionAsync(CacheGroupContext grp, GridDhtLocalPartition part) {
- GroupEvictionContext groupEvictionContext = evictionGroupsMap.computeIfAbsent(
+ GroupEvictionContext grpEvictionCtx = evictionGroupsMap.computeIfAbsent(
grp.groupId(), (k) -> new GroupEvictionContext(grp));
// Check node stop.
- if (groupEvictionContext.shouldStop())
+ if (grpEvictionCtx.shouldStop())
return;
int bucket;
synchronized (mux) {
- if (!groupEvictionContext.partIds.add(part.id()))
+ if (!grpEvictionCtx.partIds.add(part.id()))
return;
- bucket = evictionQueue.offer(new PartitionEvictionTask(part, groupEvictionContext));
+ bucket = evictionQueue.offer(new PartitionEvictionTask(part, grpEvictionCtx));
}
- groupEvictionContext.totalTasks.incrementAndGet();
+ grpEvictionCtx.totalTasks.incrementAndGet();
if (log.isDebugEnabled())
log.debug("Partition has been scheduled for eviction [grp=" + grp.cacheOrGroupName()
@@ -143,7 +143,7 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
*/
private void scheduleNextPartitionEviction(int bucket) {
// Check node stop.
- if (sharedEvictionContext.shouldStop())
+ if (sharedEvictionCtx.shouldStop())
return;
synchronized (mux) {
@@ -178,17 +178,17 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
// Print current eviction progress.
showProgress();
- GroupEvictionContext groupEvictionContext = evictionTask.groupEvictionCtx;
+ GroupEvictionContext grpEvictionCtx = evictionTask.grpEvictionCtx;
// Check that group or node stopping.
- if (groupEvictionContext.shouldStop())
+ if (grpEvictionCtx.shouldStop())
continue;
// Get permit for this task.
permits--;
// Register task future, may need if group or node will be stopped.
- groupEvictionContext.taskScheduled(evictionTask);
+ grpEvictionCtx.taskScheduled(evictionTask);
evictionTask.finishFut.listen(f -> {
synchronized (mux) {
@@ -294,7 +294,7 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
/** {@inheritDoc} */
@Override public boolean shouldStop() {
- return stop || sharedEvictionContext.shouldStop();
+ return stop || sharedEvictionCtx.shouldStop();
}
/**
@@ -384,35 +384,35 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
private final long size;
/** Eviction context. */
- private final GroupEvictionContext groupEvictionCtx;
+ private final GroupEvictionContext grpEvictionCtx;
/** */
private final GridFutureAdapter<?> finishFut = new GridFutureAdapter<>();
/**
* @param part Partition.
- * @param groupEvictionCtx Eviction context.
+ * @param grpEvictionCtx Eviction context.
*/
private PartitionEvictionTask(
GridDhtLocalPartition part,
- GroupEvictionContext groupEvictionCtx
+ GroupEvictionContext grpEvictionCtx
) {
this.part = part;
- this.groupEvictionCtx = groupEvictionCtx;
+ this.grpEvictionCtx = grpEvictionCtx;
size = part.fullSize();
}
/** {@inheritDoc} */
@Override public void run() {
- if (groupEvictionCtx.shouldStop()) {
+ if (grpEvictionCtx.shouldStop()) {
finishFut.onDone();
return;
}
try {
- boolean success = part.tryClear(groupEvictionCtx);
+ boolean success = part.tryClear(grpEvictionCtx);
if (success) {
if (part.state() == GridDhtPartitionState.EVICTED && part.markForDestroy())
@@ -425,7 +425,7 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
// Re-offer partition if clear was unsuccessful due to partition reservation.
if (!success)
- evictPartitionAsync(groupEvictionCtx.grp, part);
+ evictPartitionAsync(grpEvictionCtx.grp, part);
}
catch (Throwable ex) {
finishFut.onDone(ex);
@@ -435,9 +435,8 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
false,
true);
}
- else{
+ else
LT.error(log, ex, "Partition eviction failed, this can cause grid hang.");
- }
}
}
}
@@ -523,9 +522,8 @@ public class PartitionsEvictManager extends GridCacheSharedManagerAdapter {
int size(){
int size = 0;
- for (Queue<PartitionEvictionTask> queue : buckets) {
+ for (Queue<PartitionEvictionTask> queue : buckets)
size += queue.size();
- }
return size;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
index 913e9bc..13b03fe 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
@@ -147,7 +147,11 @@ public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearT
}
if (topFut.isDone()) {
- topVer = topFut.topologyVersion();
+ if ((topVer = topFut.topologyVersion()) == null && topFut.error() != null) {
+ onDone(topFut.error()); // Prevent stack overflow if topFut has error.
+
+ return;
+ }
if (remap)
tx.onRemap(topVer);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index b3b43b9..797221e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -3831,13 +3831,24 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter implements GridTimeou
return chainFinishFuture(finishFut, true, true, false);
if (!fastFinish) {
- final IgniteInternalFuture<?> prepareFut = prepareNearTxLocal();
+ IgniteInternalFuture<?> prepareFut;
+ try {
+ prepareFut = prepareNearTxLocal();
+ }
+ catch (Throwable t) {
+ prepareFut = prepFut;
+
+ // Properly finish prepFut in case of unchecked error.
+ assert prepareFut != null; // Prep future must be set.
+
+ ((GridNearTxPrepareFutureAdapter)prepFut).onDone(t);
+ }
prepareFut.listen(new CI1<IgniteInternalFuture<?>>() {
@Override public void apply(IgniteInternalFuture<?> f) {
try {
// Make sure that here are no exceptions.
- prepareFut.get();
+ f.get();
fut.finish(true, true, false);
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRow.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRow.java
index 92f06a3..746b94a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRow.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRow.java
@@ -20,6 +20,9 @@ package org.apache.ignite.internal.processors.cache.persistence;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.mvcc.MvccUpdateVersionAware;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
/**
@@ -55,4 +58,9 @@ public interface CacheDataRow extends MvccUpdateVersionAware, CacheSearchRow, St
* @param key Key.
*/
public void key(KeyCacheObject key);
+
+ /** {@inheritDoc} */
+ @Override public default IOVersions<? extends AbstractDataPageIO> ioVersions() {
+ return DataPageIO.VERSIONS;
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
index 3e3dc5c..b551f47 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
@@ -233,7 +233,7 @@ public class CacheDataRowAdapter implements CacheDataRow {
IoStatisticsHolder statHolder,
boolean readCacheId,
RowData rowData,
- IncompleteObject<?> incomplete,
+ @Nullable IncompleteObject<?> incomplete,
boolean skipVer
) throws IgniteCheckedException {
assert link != 0 : "link";
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index 498ccf1..3c40cdf 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -111,6 +111,7 @@ import org.apache.ignite.internal.pagemem.wal.record.MetastoreDataRecord;
import org.apache.ignite.internal.pagemem.wal.record.MvccDataEntry;
import org.apache.ignite.internal.pagemem.wal.record.MvccTxRecord;
import org.apache.ignite.internal.pagemem.wal.record.PageSnapshot;
+import org.apache.ignite.internal.pagemem.wal.record.RollbackRecord;
import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
import org.apache.ignite.internal.pagemem.wal.record.WalRecordCacheGroupAware;
import org.apache.ignite.internal.pagemem.wal.record.delta.PageDeltaRecord;
@@ -142,7 +143,6 @@ import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemor
import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionAllocationMap;
-import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionRecoverState;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteCacheSnapshotManager;
import org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotOperation;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
@@ -2730,9 +2730,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
Semaphore semaphore = new Semaphore(semaphorePertmits(exec));
+ Map<GroupPartitionId, Integer> partitionRecoveryStates = new HashMap<>();
+
WALIterator it = cctx.wal().replay(status.startPtr, recordTypePredicate);
- RestoreLogicalState restoreLogicalState = new RestoreLogicalState(status, it, lastArchivedSegment, cacheGroupsPredicate);
+ RestoreLogicalState restoreLogicalState =
+ new RestoreLogicalState(status, it, lastArchivedSegment, cacheGroupsPredicate, partitionRecoveryStates);
try {
while (it.hasNextX()) {
@@ -2742,6 +2745,36 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
break;
switch (rec.type()) {
+ case CHECKPOINT_RECORD: // Calculate initial partition states
+ CheckpointRecord cpRec = (CheckpointRecord)rec;
+
+ for (Map.Entry<Integer, CacheState> entry : cpRec.cacheGroupStates().entrySet()) {
+ CacheState cacheState = entry.getValue();
+
+ for (int i = 0; i < cacheState.size(); i++) {
+ int partId = cacheState.partitionByIndex(i);
+ byte state = cacheState.stateByIndex(i);
+
+ partitionRecoveryStates.put(new GroupPartitionId(entry.getKey(), partId), (int)state);
+ }
+ }
+
+ break;
+
+ case ROLLBACK_TX_RECORD:
+ RollbackRecord rbRec = (RollbackRecord)rec;
+
+ CacheGroupContext ctx = cctx.cache().cacheGroup(rbRec.groupId());
+
+ if (ctx != null && !ctx.isLocal()) {
+ ctx.topology().forceCreatePartition(rbRec.partitionId());
+
+ ctx.offheap().onPartitionInitialCounterUpdated(rbRec.partitionId(), rbRec.start(),
+ rbRec.range());
+ }
+
+ break;
+
case MVCC_DATA_RECORD:
case DATA_RECORD:
case ENCRYPTED_DATA_RECORD:
@@ -2773,7 +2806,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
}
applied.incrementAndGet();
- }, cacheId, dataEntry.partitionId(), exec, semaphore);
+ }, cacheDesc.groupId(), dataEntry.partitionId(), exec, semaphore);
}
break;
@@ -2794,11 +2827,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
metaStateRecord.groupId(), metaStateRecord.partitionId()
);
- PartitionRecoverState state = new PartitionRecoverState(
- (int)metaStateRecord.state(), metaStateRecord.updateCounter()
- );
-
- restoreLogicalState.partitionRecoveryStates.put(groupPartitionId, state);
+ restoreLogicalState.partitionRecoveryStates.put(groupPartitionId, (int)metaStateRecord.state());
break;
@@ -2925,7 +2954,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
}
if (dataEntry.partitionCounter() != 0)
- cacheCtx.offheap().onPartitionInitialCounterUpdated(partId, dataEntry.partitionCounter());
+ cacheCtx.offheap().onPartitionInitialCounterUpdated(partId, dataEntry.partitionCounter() - 1, 1);
break;
@@ -2944,7 +2973,7 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
cacheCtx.offheap().remove(cacheCtx, dataEntry.key(), partId, locPart);
if (dataEntry.partitionCounter() != 0)
- cacheCtx.offheap().onPartitionInitialCounterUpdated(partId, dataEntry.partitionCounter());
+ cacheCtx.offheap().onPartitionInitialCounterUpdated(partId, dataEntry.partitionCounter() - 1, 1);
break;
@@ -5347,13 +5376,13 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
assert pageStore != null : "Persistent cache should have initialize page store manager.";
for (int p = 0; p < grp.affinity().partitions(); p++) {
- if (grp.topology().localPartition(p) != null) {
- GridDhtLocalPartition part = grp.topology().localPartition(p);
+ GridDhtLocalPartition part = grp.topology().localPartition(p);
+ if (part != null) {
log.info("Partition [grp=" + grp.cacheOrGroupName()
+ ", id=" + p
+ ", state=" + part.state()
- + ", counter=" + part.updateCounter()
+ + ", counter=" + part.dataStore().partUpdateCounter()
+ ", size=" + part.fullSize() + "]");
continue;
@@ -5379,17 +5408,17 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
try {
PagePartitionMetaIO io = PagePartitionMetaIO.VERSIONS.forPage(pageAddr);
- GridDhtPartitionState partitionState = fromOrdinal(io.getPartitionState(pageAddr));
+ GridDhtPartitionState partState = fromOrdinal(io.getPartitionState(pageAddr));
- String state = partitionState != null ? partitionState.toString() : "N/A";
+ String state = partState != null ? partState.toString() : "N/A";
- long updateCounter = io.getUpdateCounter(pageAddr);
+ long updateCntr = io.getUpdateCounter(pageAddr);
long size = io.getSize(pageAddr);
log.info("Partition [grp=" + grp.cacheOrGroupName()
+ ", id=" + p
+ ", state=" + state
- + ", counter=" + updateCounter
+ + ", counter=" + updateCntr
+ ", size=" + size + "]");
}
finally {
@@ -5453,11 +5482,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
}
/**
- * @return WAL records predicate that passes only logical and mixed WAL records.
+ * @return WAL records predicate that passes only logical and mixed WAL records +
+ * CP record (used for restoring initial partition states).
*/
private IgniteBiPredicate<WALRecord.RecordType, WALPointer> logicalRecords() {
return (type, ptr) -> type.purpose() == WALRecord.RecordPurpose.LOGICAL
- || type.purpose() == WALRecord.RecordPurpose.MIXED;
+ || type.purpose() == WALRecord.RecordPurpose.MIXED || type == CHECKPOINT_RECORD;
}
/**
@@ -5670,19 +5700,23 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
*/
public class RestoreLogicalState extends RestoreStateContext {
/** States of partitions recovered during applying logical updates. */
- private final Map<GroupPartitionId, PartitionRecoverState> partitionRecoveryStates = new HashMap<>();
+ private final Map<GroupPartitionId, Integer> partitionRecoveryStates;
/**
* @param lastArchivedSegment Last archived segment index.
+ * @param partitionRecoveryStates Initial partition recovery states.
*/
- public RestoreLogicalState(CheckpointStatus status, WALIterator iterator, long lastArchivedSegment, IgnitePredicate<Integer> cacheGroupsPredicate) {
+ public RestoreLogicalState(CheckpointStatus status, WALIterator iterator, long lastArchivedSegment,
+ IgnitePredicate<Integer> cacheGroupsPredicate, Map<GroupPartitionId, Integer> partitionRecoveryStates) {
super(status, iterator, lastArchivedSegment, cacheGroupsPredicate);
+
+ this.partitionRecoveryStates = partitionRecoveryStates;
}
/**
* @return Map of restored partition states for cache groups.
*/
- public Map<GroupPartitionId, PartitionRecoverState> partitionRecoveryStates() {
+ public Map<GroupPartitionId, Integer> partitionRecoveryStates() {
return Collections.unmodifiableMap(partitionRecoveryStates);
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
index 84a23d3..942a713 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.cache.persistence;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -31,6 +32,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.cache.processor.EntryProcessor;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
import org.apache.ignite.failure.FailureContext;
import org.apache.ignite.failure.FailureType;
import org.apache.ignite.internal.pagemem.FullPageId;
@@ -45,9 +47,10 @@ import org.apache.ignite.internal.pagemem.wal.WALPointer;
import org.apache.ignite.internal.pagemem.wal.record.DataEntry;
import org.apache.ignite.internal.pagemem.wal.record.DataRecord;
import org.apache.ignite.internal.pagemem.wal.record.PageSnapshot;
+import org.apache.ignite.internal.pagemem.wal.record.RollbackRecord;
import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageInitRecord;
-import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdatePartitionDataRecord;
+import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdatePartitionDataRecordV2;
import org.apache.ignite.internal.pagemem.wal.record.delta.PartitionDestroyRecord;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
@@ -59,6 +62,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheMvccEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheTtlManager;
import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
+import org.apache.ignite.internal.processors.cache.PartitionUpdateCounter;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionPartialCountersMap;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.IgniteHistoricalIterator;
import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition;
@@ -66,12 +70,15 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.topology.Grid
import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
import org.apache.ignite.internal.processors.cache.mvcc.MvccVersion;
import org.apache.ignite.internal.processors.cache.persistence.freelist.CacheFreeListImpl;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.AbstractFreeList;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow;
import org.apache.ignite.internal.processors.cache.persistence.migration.UpgradePendingTreeToPerPartitionTask;
import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
import org.apache.ignite.internal.processors.cache.persistence.partstate.PagesAllocationRange;
import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionAllocationMap;
-import org.apache.ignite.internal.processors.cache.persistence.partstate.PartitionRecoverState;
+import org.apache.ignite.internal.processors.cache.persistence.partstorage.PartitionMetaStorage;
+import org.apache.ignite.internal.processors.cache.persistence.partstorage.PartitionMetaStorageImpl;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageMetaIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PagePartitionCountersIO;
@@ -267,14 +274,18 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
if (rowStore0 != null) {
((CacheFreeListImpl)rowStore0.freeList()).saveMetadata();
+ PartitionMetaStorage<SimpleDataRow> partStore = store.partStorage();
+
long updCntr = store.updateCounter();
long size = store.fullSize();
long rmvId = globalRemoveId().get();
+ byte[] updCntrsBytes = store.partUpdateCounter().getBytes();
+
PageMemoryEx pageMem = (PageMemoryEx)grp.dataRegion().pageMemory();
IgniteWriteAheadLogManager wal = this.ctx.wal();
- if (size > 0 || updCntr > 0) {
+ if (size > 0 || updCntr > 0 || !store.partUpdateCounter().sequential()) {
GridDhtPartitionState state = null;
// localPartition will not acquire writeLock here because create=false.
@@ -313,7 +324,46 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
boolean changed = false;
try {
- PagePartitionMetaIO io = PageIO.getPageIO(partMetaPageAddr);
+ PagePartitionMetaIOV2 io = PageIO.getPageIO(partMetaPageAddr);
+
+ long link = io.getGapsLink(partMetaPageAddr);
+
+ if (updCntrsBytes == null && link != 0) {
+ partStore.removeDataRowByLink(link, grp.statisticsHolderData());
+
+ io.setGapsLink(partMetaPageAddr, (link = 0));
+
+ changed = true;
+ }
+ else if (updCntrsBytes != null && link == 0) {
+ SimpleDataRow row = new SimpleDataRow(store.partId(), updCntrsBytes);
+
+ partStore.insertDataRow(row, grp.statisticsHolderData());
+
+ io.setGapsLink(partMetaPageAddr, (link = row.link()));
+
+ changed = true;
+ }
+ else if (updCntrsBytes != null && link != 0) {
+ byte[] prev = partStore.readRow(link);
+
+ assert prev != null : "Read null gaps using link=" + link;
+
+ if (!Arrays.equals(prev, updCntrsBytes)) {
+ partStore.removeDataRowByLink(link, grp.statisticsHolderData());
+
+ SimpleDataRow row = new SimpleDataRow(store.partId(), updCntrsBytes);
+
+ partStore.insertDataRow(row, grp.statisticsHolderData());
+
+ io.setGapsLink(partMetaPageAddr, (link = row.link()));
+
+ changed = true;
+ }
+ }
+
+ if (changed)
+ partStore.saveMetadata();
changed |= io.setUpdateCounter(partMetaPageAddr, updCntr);
changed |= io.setGlobalRemoveId(partMetaPageAddr, rmvId);
@@ -386,7 +436,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
pageCnt = io.getCandidatePageCount(partMetaPageAddr);
if (changed && PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, partMetaId, partMetaPage, wal, null))
- wal.log(new MetaPageUpdatePartitionDataRecord(
+ wal.log(new MetaPageUpdatePartitionDataRecordV2(
grpId,
partMetaId,
updCntr,
@@ -394,7 +444,8 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
(int)size, // TODO: Partition size may be long
cntrsPageId,
state == null ? -1 : (byte)state.ordinal(),
- pageCnt
+ pageCnt,
+ link
));
}
finally {
@@ -413,7 +464,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
- @Override public long restorePartitionStates(Map<GroupPartitionId, PartitionRecoverState> partitionRecoveryStates) throws IgniteCheckedException {
+ @Override public long restorePartitionStates(Map<GroupPartitionId, Integer> partitionRecoveryStates) throws IgniteCheckedException {
if (grp.isLocal() || !grp.affinityNode() || !grp.dataRegion().config().isPersistenceEnabled())
return 0;
@@ -425,7 +476,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
PageMemoryEx pageMem = (PageMemoryEx)grp.dataRegion().pageMemory();
for (int p = 0; p < grp.affinity().partitions(); p++) {
- PartitionRecoverState recoverState = partitionRecoveryStates.get(new GroupPartitionId(grp.groupId(), p));
+ Integer recoverState = partitionRecoveryStates.get(new GroupPartitionId(grp.groupId(), p));
if (ctx.pageStore().exists(grp.groupId(), p)) {
ctx.pageStore().ensure(grp.groupId(), p);
@@ -446,7 +497,8 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
GridDhtLocalPartition part = grp.topology().forceCreatePartition(p);
- onPartitionInitialCounterUpdated(p, 0);
+ // Triggers initialization of existing(having datafile) partition before acquiring cp read lock.
+ part.dataStore().init();
ctx.database().checkpointReadLock();
@@ -463,17 +515,9 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
PagePartitionMetaIO io = PagePartitionMetaIO.VERSIONS.forPage(pageAddr);
if (recoverState != null) {
- io.setPartitionState(pageAddr, (byte) recoverState.stateId());
+ io.setPartitionState(pageAddr, (byte) recoverState.intValue());
- changed = updateState(part, recoverState.stateId());
-
- if (recoverState.stateId() == GridDhtPartitionState.OWNING.ordinal()
- || (recoverState.stateId() == GridDhtPartitionState.MOVING.ordinal()
- && part.initialUpdateCounter() < recoverState.updateCounter())) {
- part.initialUpdateCounter(recoverState.updateCounter());
-
- changed = true;
- }
+ changed = updateState(part, recoverState);
if (log.isDebugEnabled())
log.debug("Restored partition state (from WAL) " +
@@ -503,12 +547,10 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
ctx.database().checkpointReadUnlock();
}
}
- else if (recoverState != null) {
+ else if (recoverState != null && recoverState >= 0) { // Pre-create partition if having valid state.
GridDhtLocalPartition part = grp.topology().forceCreatePartition(p);
- onPartitionInitialCounterUpdated(p, recoverState.updateCounter());
-
- updateState(part, recoverState.stateId());
+ updateState(part, recoverState);
processed++;
@@ -816,15 +858,12 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
- @Override public void onPartitionInitialCounterUpdated(int part, long cntr) {
+ @Override public void onPartitionInitialCounterUpdated(int part, long start, long delta) {
CacheDataStore store = partDataStores.get(part);
assert store != null;
- long oldCnt = store.initialUpdateCounter();
-
- if (oldCnt < cntr)
- store.updateInitialCounter(cntr);
+ store.updateInitialCounter(start, delta);
}
/** {@inheritDoc} */
@@ -911,6 +950,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
return new Metas(
new RootPage(new FullPageId(metastoreRoot, grpId), allocated),
new RootPage(new FullPageId(reuseListRoot, grpId), allocated),
+ null,
null);
}
finally {
@@ -951,7 +991,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
WALIterator it = grp.shared().wal().replay(minPtr);
- WALHistoricalIterator iterator = new WALHistoricalIterator(grp, partCntrs, it);
+ WALHistoricalIterator iterator = new WALHistoricalIterator(log, grp, partCntrs, it);
// Add historical partitions which are unabled to reserve to missing set.
missing.addAll(iterator.missingParts);
@@ -1024,7 +1064,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
for (CacheDataStore store : partDataStores.values()) {
assert store instanceof GridCacheDataStore;
- CacheFreeListImpl freeList = ((GridCacheDataStore)store).freeList;
+ AbstractFreeList freeList = ((GridCacheDataStore)store).freeList;
if (freeList == null)
continue;
@@ -1046,7 +1086,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
for (CacheDataStore store : partDataStores.values()) {
assert store instanceof GridCacheDataStore;
- CacheFreeListImpl freeList = ((GridCacheDataStore)store).freeList;
+ AbstractFreeList freeList = ((GridCacheDataStore)store).freeList;
if (freeList == null)
continue;
@@ -1094,6 +1134,9 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
/** */
private static final long serialVersionUID = 0L;
+ /** Logger. */
+ private IgniteLogger log;
+
/** Cache context. */
private final CacheGroupContext grp;
@@ -1118,24 +1161,34 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
/** */
private DataEntry next;
- /** Flag indicates that partition belongs to current {@link #next} is finished and no longer needs to rebalance. */
- private boolean reachedPartitionEnd;
+ /**
+ * Rebalanced counters in the range from initialUpdateCntr to updateCntr.
+ * Invariant: initUpdCntr[idx] + rebalancedCntrs[idx] = updateCntr[idx]
+ */
+ private long[] rebalancedCntrs;
- /** Flag indicates that update counters for requested partitions have been reached and done.
- * It means that no further iteration is needed. */
- private boolean doneAllPartitions;
+ /** A partition what will be finished on next iteration. */
+ private int donePart = -1;
/**
+ * @param log Logger.
* @param grp Cache context.
* @param walIt WAL iterator.
*/
- private WALHistoricalIterator(CacheGroupContext grp, CachePartitionPartialCountersMap partMap, WALIterator walIt) {
+ private WALHistoricalIterator(IgniteLogger log, CacheGroupContext grp, CachePartitionPartialCountersMap partMap,
+ WALIterator walIt) {
+ this.log = log;
this.grp = grp;
this.partMap = partMap;
this.walIt = walIt;
cacheIds = grp.cacheIds();
+ rebalancedCntrs = new long[partMap.size()];
+
+ for (int i = 0; i < rebalancedCntrs.length; i++)
+ rebalancedCntrs[i] = partMap.initialUpdateCounterAt(i);
+
reservePartitions();
advance();
@@ -1194,13 +1247,19 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
CacheDataRow val = new DataEntryRow(next);
- if (reachedPartitionEnd) {
- doneParts.add(next.partitionId());
+ if (donePart != -1) {
+ int pIdx = partMap.partitionIndex(donePart);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Partition done [grpId=" + grp.groupId() +
+ ", partId=" + donePart +
+ ", from=" + partMap.initialUpdateCounterAt(pIdx) +
+ ", to=" + partMap.updateCounterAt(pIdx) + ']');
+ }
- reachedPartitionEnd = false;
+ doneParts.add(donePart);
- if (doneParts.size() == partMap.size())
- doneAllPartitions = true;
+ donePart = -1;
}
advance();
@@ -1259,10 +1318,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
private void advance() {
next = null;
- if (doneAllPartitions)
- return;
-
- while (true) {
+ outer: while (doneParts.size() != partMap.size()) {
if (entryIt != null) {
while (entryIt.hasNext()) {
DataEntry entry = entryIt.next();
@@ -1277,8 +1333,10 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
long to = partMap.updateCounterAt(idx);
if (entry.partitionCounter() > from && entry.partitionCounter() <= to) {
- if (entry.partitionCounter() == to)
- reachedPartitionEnd = true;
+ // Partition will be marked as done for current entry on next iteration.
+ if (++rebalancedCntrs[idx] == to ||
+ entry.partitionCounter() == to && grp.hasAtomicCaches())
+ donePart = entry.partitionId();
next = entry;
@@ -1290,6 +1348,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
entryIt = null;
+ // Search for next DataEntry while applying rollback counters.
while (walIt.hasNext()) {
IgniteBiTuple<WALPointer, WALRecord> rec = walIt.next();
@@ -1297,14 +1356,38 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
DataRecord data = (DataRecord)rec.get2();
entryIt = data.writeEntries().iterator();
+
// Move on to the next valid data entry.
+ continue outer;
+ }
+ else if (rec.get2() instanceof RollbackRecord) {
+ RollbackRecord rbRec = (RollbackRecord)rec.get2();
- break;
+ if (grp.groupId() == rbRec.groupId()) {
+ int idx = partMap.partitionIndex(rbRec.partitionId());
+
+ if (idx < 0 || missingParts.contains(idx))
+ continue;
+
+ long from = partMap.initialUpdateCounterAt(idx);
+ long to = partMap.updateCounterAt(idx);
+
+ rebalancedCntrs[idx] += rbRec.overlap(from, to);
+
+ if (rebalancedCntrs[idx] == partMap.updateCounterAt(idx)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Partition done [partId=" + donePart +
+ " from=" + from + " to=" + to + ']');
+ }
+
+ doneParts.add(rbRec.partitionId()); // Add to done set immediately.
+ }
+ }
}
}
- if (entryIt == null)
- return;
+ assert entryIt != null || doneParts.size() == partMap.size() :
+ "Reached end of WAL but not all partitions are done";
}
}
}
@@ -1440,14 +1523,19 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
@GridToStringInclude
private final RootPage pendingTreeRoot;
+ /** */
+ @GridToStringInclude
+ private final RootPage partMetastoreReuseListRoot;
+
/**
* @param treeRoot Metadata storage root.
* @param reuseListRoot Reuse list root.
*/
- Metas(RootPage treeRoot, RootPage reuseListRoot, RootPage pendingTreeRoot) {
+ Metas(RootPage treeRoot, RootPage reuseListRoot, RootPage pendingTreeRoot, RootPage partMetastoreReuseListRoot) {
this.treeRoot = treeRoot;
this.reuseListRoot = reuseListRoot;
this.pendingTreeRoot = pendingTreeRoot;
+ this.partMetastoreReuseListRoot = partMetastoreReuseListRoot;
}
/** {@inheritDoc} */
@@ -1467,13 +1555,13 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
private String name;
/** */
- private volatile CacheFreeListImpl freeList;
+ private volatile AbstractFreeList<CacheDataRow> freeList;
/** */
private PendingEntriesTree pendingTree;
/** */
- private volatile CacheDataStore delegate;
+ private volatile CacheDataStoreImpl delegate;
/**
* Cache id which should be throttled.
@@ -1488,6 +1576,9 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
private volatile long nextStoreCleanTime;
/** */
+ private PartitionMetaStorage<SimpleDataRow> partStorage;
+
+ /** */
private final boolean exists;
/** */
@@ -1512,7 +1603,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
* @throws IgniteCheckedException If failed.
*/
private CacheDataStore init0(boolean checkExists) throws IgniteCheckedException {
- CacheDataStore delegate0 = delegate;
+ CacheDataStoreImpl delegate0 = delegate;
if (delegate0 != null)
return delegate0;
@@ -1532,7 +1623,9 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
if (PageIdUtils.partId(metas.reuseListRoot.pageId().pageId()) != partId ||
PageIdUtils.partId(metas.treeRoot.pageId().pageId()) != partId ||
- PageIdUtils.partId(metas.pendingTreeRoot.pageId().pageId()) != partId) {
+ PageIdUtils.partId(metas.pendingTreeRoot.pageId().pageId()) != partId ||
+ PageIdUtils.partId(metas.partMetastoreReuseListRoot.pageId().pageId()) != partId
+ ) {
throw new IgniteCheckedException("Invalid meta root allocated [" +
"cacheOrGroupName=" + grp.cacheOrGroupName() +
", partId=" + partId +
@@ -1558,6 +1651,25 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
};
+ RootPage partMetastoreReuseListRoot = metas.partMetastoreReuseListRoot;
+
+ partStorage = new PartitionMetaStorageImpl<SimpleDataRow>(
+ grp.groupId(),
+ grp.cacheOrGroupName() + "-partstore-" + partId,
+ grp.dataRegion().memoryMetrics(),
+ grp.dataRegion(),
+ freeList,
+ ctx.wal(),
+ partMetastoreReuseListRoot.pageId().pageId(),
+ partMetastoreReuseListRoot.isAllocated()) {
+ /** {@inheritDoc} */
+ @Override protected long allocatePageNoReuse() throws IgniteCheckedException {
+ assert grp.shared().database().checkpointLockIsHeldByThread();
+
+ return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA);
+ }
+ };
+
CacheDataRowStore rowStore = new CacheDataRowStore(grp, freeList, partId);
RootPage treeRoot = metas.treeRoot;
@@ -1642,14 +1754,18 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
try {
if (PageIO.getType(pageAddr) != 0) {
- PagePartitionMetaIO io = PagePartitionMetaIO.VERSIONS.latest();
+ PagePartitionMetaIOV2 io = (PagePartitionMetaIOV2)PagePartitionMetaIO.VERSIONS.latest();
Map<Integer, Long> cacheSizes = null;
if (grp.sharedGroup())
cacheSizes = readSharedGroupCacheSizes(pageMem, grpId, io.getCountersPageId(pageAddr));
- delegate0.init(io.getSize(pageAddr), io.getUpdateCounter(pageAddr), cacheSizes);
+ long link = io.getGapsLink(pageAddr);
+
+ byte[] data = link == 0 ? null : partStorage.readRow(link);
+
+ delegate0.restoreState(io.getSize(pageAddr), io.getUpdateCounter(pageAddr), cacheSizes, data);
globalRemoveId().setIfGreater(io.getGlobalRemoveId(pageAddr));
}
@@ -1704,28 +1820,32 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
try {
boolean allocated = false;
boolean pendingTreeAllocated = false;
+ boolean partMetastoreReuseListAllocated = false;
long pageAddr = pageMem.writeLock(grpId, partMetaId, partMetaPage);
try {
- long treeRoot, reuseListRoot, pendingTreeRoot;
+ long treeRoot, reuseListRoot, pendingTreeRoot, partMetaStoreReuseListRoot;
// Initialize new page.
if (PageIO.getType(pageAddr) != PageIO.T_PART_META) {
- PagePartitionMetaIO io = PagePartitionMetaIO.VERSIONS.latest();
+ PagePartitionMetaIOV2 io = (PagePartitionMetaIOV2)PagePartitionMetaIO.VERSIONS.latest();
io.initNewPage(pageAddr, partMetaId, pageMem.realPageSize(grpId));
treeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
reuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
pendingTreeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
+ partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
assert PageIdUtils.flag(treeRoot) == PageMemory.FLAG_DATA;
assert PageIdUtils.flag(reuseListRoot) == PageMemory.FLAG_DATA;
assert PageIdUtils.flag(pendingTreeRoot) == PageMemory.FLAG_DATA;
+ assert PageIdUtils.flag(partMetaStoreReuseListRoot) == PageMemory.FLAG_DATA;
io.setTreeRoot(pageAddr, treeRoot);
io.setReuseListRoot(pageAddr, reuseListRoot);
io.setPendingTreeRoot(pageAddr, pendingTreeRoot);
+ io.setPartitionMetaStoreReuseListRoot(pageAddr, partMetaStoreReuseListRoot);
if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, partMetaId, partMetaPage, wal, null)) {
wal.log(new PageSnapshot(new FullPageId(partMetaId, grpId), pageAddr,
@@ -1740,14 +1860,14 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
treeRoot = io.getTreeRoot(pageAddr);
reuseListRoot = io.getReuseListRoot(pageAddr);
- int pageVersion = PagePartitionMetaIO.getVersion(pageAddr);
+ int pageVer = PagePartitionMetaIO.getVersion(pageAddr);
- if (pageVersion < 2) {
- assert pageVersion == 1;
+ if (pageVer < 2) {
+ assert pageVer == 1;
if (log.isDebugEnabled())
log.info("Upgrade partition meta page version: [part=" + partId +
- ", grpId=" + grpId + ", oldVer=" + pageVersion +
+ ", grpId=" + grpId + ", oldVer=" + pageVer +
", newVer=" + io.getVersion()
);
@@ -1756,8 +1876,10 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
((PagePartitionMetaIOV2)io).upgradePage(pageAddr);
pendingTreeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
+ partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
io.setPendingTreeRoot(pageAddr, pendingTreeRoot);
+ io.setPartitionMetaStoreReuseListRoot(pageAddr, partMetaStoreReuseListRoot);
if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, partMetaId, partMetaPage, wal,
null)) {
@@ -1765,10 +1887,24 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
pageMem.pageSize(), pageMem.realPageSize(grpId)));
}
- pendingTreeAllocated = true;
+ pendingTreeAllocated = partMetastoreReuseListAllocated = true;
}
- else
+ else {
pendingTreeRoot = io.getPendingTreeRoot(pageAddr);
+ partMetaStoreReuseListRoot = io.getPartitionMetaStoreReuseListRoot(pageAddr);
+
+ if (partMetaStoreReuseListRoot == 0) {
+ partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA);
+
+ if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, partMetaId, partMetaPage, wal,
+ null)) {
+ wal.log(new PageSnapshot(new FullPageId(partMetaId, grpId), pageAddr,
+ pageMem.pageSize(), pageMem.realPageSize(grpId)));
+ }
+
+ partMetastoreReuseListAllocated = true;
+ }
+ }
if (PageIdUtils.flag(treeRoot) != PageMemory.FLAG_DATA)
throw new StorageException("Wrong tree root page id flag: treeRoot="
@@ -1781,15 +1917,21 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
if (PageIdUtils.flag(pendingTreeRoot) != PageMemory.FLAG_DATA)
throw new StorageException("Wrong pending tree root page id flag: reuseListRoot="
+ U.hexLong(reuseListRoot) + ", part=" + partId + ", grpId=" + grpId);
+
+ if (PageIdUtils.flag(partMetaStoreReuseListRoot) != PageMemory.FLAG_DATA)
+ throw new StorageException("Wrong partition meta store list root page id flag: partMetaStoreReuseListRoot="
+ + U.hexLong(partMetaStoreReuseListRoot) + ", part=" + partId + ", grpId=" + grpId);
}
return new Metas(
new RootPage(new FullPageId(treeRoot, grpId), allocated),
new RootPage(new FullPageId(reuseListRoot, grpId), allocated),
- new RootPage(new FullPageId(pendingTreeRoot, grpId), allocated || pendingTreeAllocated));
+ new RootPage(new FullPageId(pendingTreeRoot, grpId), allocated || pendingTreeAllocated),
+ new RootPage(new FullPageId(partMetaStoreReuseListRoot, grpId), allocated || partMetastoreReuseListAllocated));
}
finally {
- pageMem.writeUnlock(grpId, partMetaId, partMetaPage, null, allocated || pendingTreeAllocated);
+ pageMem.writeUnlock(grpId, partMetaId, partMetaPage, null,
+ allocated || pendingTreeAllocated || partMetastoreReuseListAllocated);
}
}
finally {
@@ -1798,6 +1940,16 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
+ @Override public boolean init() {
+ try {
+ return init0(true) != null;
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
@Override public int partId() {
return partId;
}
@@ -1888,10 +2040,34 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
- @Override public long getAndIncrementUpdateCounter(long delta) {
+ @Override public long reservedCounter() {
+ try {
+ CacheDataStore delegate0 = init0(true);
+
+ return delegate0 == null ? 0 : delegate0.reservedCounter();
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public PartitionUpdateCounter partUpdateCounter() {
try {
CacheDataStore delegate0 = init0(true);
+ return delegate0 == null ? null : delegate0.partUpdateCounter();
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getAndIncrementUpdateCounter(long delta) {
+ try {
+ CacheDataStore delegate0 = init0(false);
+
return delegate0 == null ? 0 : delegate0.getAndIncrementUpdateCounter(delta);
}
catch (IgniteCheckedException e) {
@@ -1900,8 +2076,18 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
- @Override public void init(long size, long updCntr, @Nullable Map<Integer, Long> cacheSizes) {
- throw new IllegalStateException("Should be never called.");
+ @Override public long reserve(long delta) {
+ try {
+ CacheDataStore delegate0 = init0(false);
+
+ if (delegate0 == null)
+ throw new IllegalStateException("Should be never called.");
+
+ return delegate0.reserve(delta);
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
}
/** {@inheritDoc} */
@@ -1918,12 +2104,11 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
- @Override public void updateCounter(long start, long delta) {
+ @Override public boolean updateCounter(long start, long delta) {
try {
CacheDataStore delegate0 = init0(false);
- if (delegate0 != null)
- delegate0.updateCounter(start, delta);
+ return delegate0 != null && delegate0.updateCounter(start, delta);
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
@@ -1947,7 +2132,10 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
try {
CacheDataStore delegate0 = init0(false);
- return delegate0 == null ? 0 : delegate0.nextUpdateCounter();
+ if (delegate0 == null)
+ throw new IllegalStateException("Should be never called.");
+
+ return delegate0.nextUpdateCounter();
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
@@ -1967,12 +2155,14 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
}
/** {@inheritDoc} */
- @Override public void updateInitialCounter(long cntr) {
+ @Override public void updateInitialCounter(long start, long delta) {
try {
CacheDataStore delegate0 = init0(true);
- if (delegate0 != null)
- delegate0.updateInitialCounter(cntr);
+ if (delegate0 == null)
+ throw new IllegalStateException("Should be never called.");
+
+ delegate0.updateInitialCounter(start, delta);
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
@@ -2495,6 +2685,25 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
if (delegate0 != null)
delegate0.preload();
}
+
+ /** {@inheritDoc} */
+ @Override public void resetUpdateCounter() {
+ try {
+ CacheDataStore delegate0 = init0(true);
+
+ if (delegate0 == null)
+ return;
+
+ delegate0.resetUpdateCounter();
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
+
+ @Override public PartitionMetaStorage partStorage() {
+ return partStorage;
+ }
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/RowStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/RowStore.java
index 91fd207..9a3d9d2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/RowStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/RowStore.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.processors.cache.persistence;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.PageIdUtils;
import org.apache.ignite.internal.pagemem.PageMemory;
import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import org.apache.ignite.internal.processors.cache.CacheObjectContext;
@@ -26,6 +27,7 @@ import org.apache.ignite.internal.processors.cache.persistence.freelist.FreeList
import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler;
import org.apache.ignite.internal.processors.query.GridQueryRowCacheCleaner;
import org.apache.ignite.internal.stat.IoStatisticsHolder;
+import org.apache.ignite.internal.util.typedef.internal.U;
/**
* Data store for H2 rows.
@@ -109,6 +111,10 @@ public class RowStore {
ctx.database().checkpointReadUnlock();
}
}
+
+ assert row.key().partition() == PageIdUtils.partId(row.link()) :
+ "Constructed a link with invalid partition ID [partId=" + row.key().partition() +
+ ", link=" + U.hexLong(row.link()) + ']';
}
/**
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
index 133f0a1..d8fe3a4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
@@ -18,6 +18,8 @@
package org.apache.ignite.internal.processors.cache.persistence;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
/**
* Simple interface for data, store in some RowStore.
@@ -49,4 +51,9 @@ public interface Storable {
* which is entirely available on the very first page followed by the row link.
*/
public int headerSize();
+
+ /**
+ * @return I/O for handling this storable.
+ */
+ public IOVersions<? extends AbstractDataPageIO> ioVersions();
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/CheckpointEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/CheckpointEntry.java
index c26e0a3..e7bcb05 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/CheckpointEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/CheckpointEntry.java
@@ -20,7 +20,6 @@ package org.apache.ignite.internal.processors.cache.persistence.checkpoint;
import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@@ -275,7 +274,7 @@ public class CheckpointEntry {
if (stateRec == null)
return Collections.emptyMap();
- Map<Integer, GroupState> grpStates = new HashMap<>(stateRec.size());
+ Map<Integer, GroupState> grpStates = U.newHashMap(stateRec.size());
for (Integer grpId : stateRec.keySet()) {
CacheState recState = stateRec.get(grpId);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java
index 958fb31..5742b74 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java
@@ -34,7 +34,6 @@ import org.apache.ignite.internal.processors.cache.persistence.Storable;
import org.apache.ignite.internal.processors.cache.persistence.evict.PageEvictionTracker;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.LongListReuseBag;
import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseBag;
@@ -484,23 +483,32 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp
long pageId = 0L;
- for (int b = remaining < MIN_SIZE_FOR_DATA_PAGE ? bucket(remaining, false) + 1 : REUSE_BUCKET; b < BUCKETS; b++) {
- pageId = takeEmptyPage(b, ioVersions(), statHolder);
+ if (remaining < MIN_SIZE_FOR_DATA_PAGE) {
+ for (int b = bucket(remaining, false) + 1; b < BUCKETS - 1; b++) {
+ pageId = takeEmptyPage(b, row.ioVersions(), statHolder);
- if (pageId != 0L)
- break;
+ if (pageId != 0L)
+ break;
+ }
+ }
+
+ if (pageId == 0L) { // Handle reuse bucket.
+ if (reuseList == this)
+ pageId = takeEmptyPage(REUSE_BUCKET, row.ioVersions(), statHolder);
+ else
+ pageId = reuseList.takeRecycledPage();
}
- AbstractDataPageIO<T> initIo = null;
+ AbstractDataPageIO initIo = null;
if (pageId == 0L) {
pageId = allocateDataPage(row.partition());
- initIo = ioVersions().latest();
+ initIo = row.ioVersions().latest();
}
- else if (PageIdUtils.tag(pageId) != PageIdAllocator.FLAG_DATA)
- pageId = initReusedPage(pageId, row.partition(), statHolder);
- else
+ else if (PageIdUtils.tag(pageId) != PageIdAllocator.FLAG_DATA) // Page is taken from reuse bucket.
+ pageId = initReusedPage(row, pageId, row.partition(), statHolder);
+ else // Page is taken from free space bucket. For in-memory mode partition must be changed.
pageId = PageIdUtils.changePartitionId(pageId, (row.partition()));
written = write(pageId, writeRow, initIo, row, written, FAIL_I, statHolder);
@@ -525,7 +533,7 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp
*
* @see PagesList#initReusedPage(long, long, long, int, byte, PageIO)
*/
- private long initReusedPage(long reusedPageId, int partId,
+ private long initReusedPage(T row, long reusedPageId, int partId,
IoStatisticsHolder statHolder) throws IgniteCheckedException {
long reusedPage = acquirePage(reusedPageId, statHolder);
try {
@@ -535,7 +543,7 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp
try {
return initReusedPage(reusedPageId, reusedPage, reusedPageAddr,
- partId, PageIdAllocator.FLAG_DATA, ioVersions().latest());
+ partId, PageIdAllocator.FLAG_DATA, row.ioVersions().latest());
}
finally {
writeUnlock(reusedPageId, reusedPage, reusedPageAddr, true);
@@ -694,11 +702,6 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp
}
}
- /**
- * @return IOVersions.
- */
- public abstract IOVersions<? extends AbstractDataPageIO<T>> ioVersions();
-
/** {@inheritDoc} */
@Override public String toString() {
return "FreeList [name=" + name + ']';
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeListImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeListImpl.java
index 625c0b1..c1a58de 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeListImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeListImpl.java
@@ -23,9 +23,6 @@ import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPageIO;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
import org.apache.ignite.internal.stat.IoStatisticsHolder;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -51,17 +48,12 @@ public class CacheFreeListImpl extends AbstractFreeList<CacheDataRow> {
}
/** {@inheritDoc} */
- @Override public IOVersions<? extends AbstractDataPageIO<CacheDataRow>> ioVersions() {
- return DataPageIO.VERSIONS;
- }
-
- /** {@inheritDoc} */
@Override public void insertDataRow(CacheDataRow row, IoStatisticsHolder statHolder) throws IgniteCheckedException {
super.insertDataRow(row, statHolder);
assert row.key().partition() == PageIdUtils.partId(row.link()) :
"Constructed a link with invalid partition ID [partId=" + row.key().partition() +
- ", link=" + U.hexLong(row.link()) + ']';
+ ", link=" + U.hexLong(row.link()) + ']';
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index e5cb3a6..1855578 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -660,7 +660,7 @@ public abstract class PagesList extends DataStructure {
* @throws IgniteCheckedException If failed.
*/
protected final void put(
- ReuseBag bag,
+ @Nullable ReuseBag bag,
final long dataId,
final long dataPage,
final long dataAddr,
@@ -669,10 +669,13 @@ public abstract class PagesList extends DataStructure {
throws IgniteCheckedException {
assert bag == null ^ dataAddr == 0L;
+ if (bag != null && bag.isEmpty()) // Skip allocating stripe for empty bag.
+ return;
+
for (int lockAttempt = 0; ;) {
Stripe stripe = getPageForPut(bucket, bag);
- // No need to continue if bag has been utilized at getPageForPut.
+ // No need to continue if bag has been utilized at getPageForPut (free page can be used for pagelist).
if (bag != null && bag.isEmpty())
return;
@@ -936,7 +939,6 @@ public abstract class PagesList extends DataStructure {
int idx = io.addPage(prevAddr, nextId, pageSize());
if (idx == -1) { // Attempt to add page failed: the node page is full.
-
final long nextPage = acquirePage(nextId, statHolder);
try {
@@ -1095,7 +1097,7 @@ public abstract class PagesList extends DataStructure {
* @return Removed page ID.
* @throws IgniteCheckedException If failed.
*/
- protected final long takeEmptyPage(int bucket, @Nullable IOVersions initIoVers,
+ protected long takeEmptyPage(int bucket, @Nullable IOVersions initIoVers,
IoStatisticsHolder statHolder) throws IgniteCheckedException {
for (int lockAttempt = 0; ;) {
Stripe stripe = getPageForTake(bucket);
@@ -1278,6 +1280,8 @@ public abstract class PagesList extends DataStructure {
}
/**
+ * Removes data page from bucket, merges bucket list if needed.
+ *
* @param dataId Data page ID.
* @param dataPage Data page pointer.
* @param dataAddr Data page address.
@@ -1642,7 +1646,7 @@ public abstract class PagesList extends DataStructure {
public volatile long tailId;
/** */
- volatile boolean empty;
+ public volatile boolean empty;
/**
* @param tailId Tail ID.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/SimpleDataRow.java
similarity index 51%
copy from modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java
copy to modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/SimpleDataRow.java
index 2d7b0a6..6061ff7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/SimpleDataRow.java
@@ -15,60 +15,68 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.persistence.metastorage;
+package org.apache.ignite.internal.processors.cache.persistence.freelist;
import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.pagemem.PageIdAllocator;
import org.apache.ignite.internal.processors.cache.persistence.Storable;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.SimpleDataPageIO;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
/**
- *
+ * Implementation of {@link Storable} which holds byte array of variable length.
*/
-public class MetastorageDataRow implements MetastorageSearchRow, Storable {
+public class SimpleDataRow implements Storable {
/** */
private long link;
/** */
- private String key;
+ private final int part;
/** */
- private byte[] value;
+ @GridToStringExclude
+ private final byte[] val;
- /** */
- public MetastorageDataRow(long link, String key, byte[] value) {
+ /**
+ * @param link Link.
+ * @param part Partition.
+ * @param val Value.
+ */
+ public SimpleDataRow(long link, int part, byte[] val) {
this.link = link;
- this.key = key;
- this.value = value;
- }
-
- /** */
- public MetastorageDataRow(String key, byte[] value) {
- this.key = key;
- this.value = value;
+ this.part = part;
+ this.val = val;
}
/**
- * @return Key.
+ * @param part Partition.
+ * @param val Value.
*/
- @Override public String key() {
- return key;
+ public SimpleDataRow(int part, byte[] val) {
+ this.part = part;
+ this.val = val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void link(long link) {
+ this.link = link;
}
/** {@inheritDoc} */
- @Override
- public int hash() {
- return key.hashCode();
+ @Override public long link() {
+ return link;
}
/** {@inheritDoc} */
- @Override
- public int partition() {
- return MetaStorage.PRESERVE_LEGACY_METASTORAGE_PARTITION_ID ? PageIdAllocator.OLD_METASTORE_PARTITION: PageIdAllocator.METASTORE_PARTITION;
+ @Override public int partition() {
+ return part;
}
/** {@inheritDoc} */
@Override public int size() throws IgniteCheckedException {
- return 4 + value().length;
+ return 2 /** Fragment size */ + 2 /** Row size */ + value().length;
}
/** {@inheritDoc} */
@@ -77,27 +85,17 @@ public class MetastorageDataRow implements MetastorageSearchRow, Storable {
}
/** {@inheritDoc} */
- @Override
- public void link(long link) {
- this.link = link;
+ public byte[] value() {
+ return val;
}
/** {@inheritDoc} */
- @Override
- public long link() {
- return link;
- }
-
- /**
- * @return Value.
- */
- public byte[] value() {
- return value;
+ @Override public IOVersions<? extends AbstractDataPageIO> ioVersions() {
+ return SimpleDataPageIO.VERSIONS;
}
/** {@inheritDoc} */
- @Override
- public String toString() {
- return "key=" + key;
+ @Override public String toString() {
+ return S.toString(SimpleDataRow.class, this, "len", val.length);
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
index cfab287..331da92 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java
@@ -50,7 +50,6 @@ import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageInitRecord;
import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
-import org.apache.ignite.internal.processors.cache.IncompleteObject;
import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
import org.apache.ignite.internal.processors.cache.persistence.DbCheckpointListener;
@@ -58,15 +57,10 @@ import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabase
import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
import org.apache.ignite.internal.processors.cache.persistence.RootPage;
import org.apache.ignite.internal.processors.cache.persistence.StorageException;
-import org.apache.ignite.internal.processors.cache.persistence.freelist.AbstractFreeList;
import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
+import org.apache.ignite.internal.processors.cache.persistence.partstorage.PartitionMetaStorageImpl;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PagePartitionMetaIO;
-import org.apache.ignite.internal.processors.cache.persistence.tree.io.SimpleDataPageIO;
-import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler;
import org.apache.ignite.internal.processors.failure.FailureProcessor;
import org.apache.ignite.internal.util.lang.GridCursor;
@@ -79,8 +73,6 @@ import org.jetbrains.annotations.NotNull;
import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA;
import static org.apache.ignite.internal.pagemem.PageIdAllocator.OLD_METASTORE_PARTITION;
-import static org.apache.ignite.internal.pagemem.PageIdUtils.itemId;
-import static org.apache.ignite.internal.pagemem.PageIdUtils.pageId;
/**
* General purpose key-value local-only storage.
@@ -104,7 +96,6 @@ public class MetaStorage implements DbCheckpointListener, ReadWriteMetastorage {
/** Temporary metastorage buffer size (file). */
private static final int TEMPORARY_METASTORAGE_BUFFER_SIZE = 1024 * 1024;
-
/** */
private final IgniteWriteAheadLogManager wal;
@@ -136,7 +127,7 @@ public class MetaStorage implements DbCheckpointListener, ReadWriteMetastorage {
private RootPage reuseListRoot;
/** */
- private FreeListImpl freeList;
+ private PartitionMetaStorageImpl<MetastorageDataRow> partStorage;
/** */
private SortedMap<String, byte[]> lastUpdates;
@@ -245,14 +236,18 @@ public class MetaStorage implements DbCheckpointListener, ReadWriteMetastorage {
getOrAllocateMetas(partId = PageIdAllocator.METASTORE_PARTITION);
if (!empty) {
- freeList = new FreeListImpl(METASTORAGE_CACHE_ID, "metastorage",
+ partStorage = new PartitionMetaStorageImpl<MetastorageDataRow>(METASTORAGE_CACHE_ID, "metastorage",
regionMetrics, dataRegion, null, wal, reuseListRoot.pageId().pageId(),
- reuseListRoot.isAllocated());
+ reuseListRoot.isAllocated()) {
+ @Override protected long allocatePageNoReuse() throws IgniteCheckedException {
+ return pageMem.allocatePage(grpId, partId, FLAG_DATA);
+ }
+ };
- MetastorageRowStore rowStore = new MetastorageRowStore(freeList, db);
+ MetastorageRowStore rowStore = new MetastorageRowStore(partStorage, db);
tree = new MetastorageTree(METASTORAGE_CACHE_ID, dataRegion.pageMemory(), wal, rmvId,
- freeList, rowStore, treeRoot.pageId().pageId(), treeRoot.isAllocated(), failureProcessor, partId);
+ partStorage, rowStore, treeRoot.pageId().pageId(), treeRoot.isAllocated(), failureProcessor, partId);
if (!readOnly)
((GridCacheDatabaseSharedManager)db).addCheckpointListener(this);
@@ -578,14 +573,14 @@ public class MetaStorage implements DbCheckpointListener, ReadWriteMetastorage {
Executor executor = ctx.executor();
if (executor == null) {
- freeList.saveMetadata();
+ partStorage.saveMetadata();
saveStoreMetadata();
}
else {
executor.execute(() -> {
try {
- freeList.saveMetadata();
+ partStorage.saveMetadata();
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
@@ -605,7 +600,7 @@ public class MetaStorage implements DbCheckpointListener, ReadWriteMetastorage {
/** {@inheritDoc} */
@Override public void beforeCheckpointBegin(Context ctx) throws IgniteCheckedException {
- freeList.saveMetadata();
+ partStorage.saveMetadata();
}
/** {@inheritDoc} */
@@ -663,108 +658,6 @@ public class MetaStorage implements DbCheckpointListener, ReadWriteMetastorage {
}
}
- /** */
- public class FreeListImpl extends AbstractFreeList<MetastorageDataRow> {
- /** {@inheritDoc} */
- FreeListImpl(int cacheId, String name, DataRegionMetricsImpl regionMetrics, DataRegion dataRegion,
- ReuseList reuseList,
- IgniteWriteAheadLogManager wal, long metaPageId, boolean initNew) throws IgniteCheckedException {
- super(cacheId, name, regionMetrics, dataRegion, reuseList, wal, metaPageId, initNew);
- }
-
- /** {@inheritDoc} */
- @Override public IOVersions<? extends AbstractDataPageIO<MetastorageDataRow>> ioVersions() {
- return SimpleDataPageIO.VERSIONS;
- }
-
- /** {@inheritDoc} */
- @Override protected long allocatePageNoReuse() throws IgniteCheckedException {
- return pageMem.allocatePage(grpId, partId, FLAG_DATA);
- }
-
- /**
- * Read row from data pages.
- */
- final MetastorageDataRow readRow(String key, long link)
- throws IgniteCheckedException {
- assert link != 0 : "link";
-
- long nextLink = link;
- IncompleteObject incomplete = null;
- int size = 0;
-
- boolean first = true;
-
- do {
- final long pageId = pageId(nextLink);
-
- final long page = pageMem.acquirePage(grpId, pageId);
-
- try {
- long pageAddr = pageMem.readLock(grpId, pageId, page); // Non-empty data page must not be recycled.
-
- assert pageAddr != 0L : nextLink;
-
- try {
- SimpleDataPageIO io = (SimpleDataPageIO)ioVersions().forPage(pageAddr);
-
- //MetaStorage never encrypted so realPageSize == pageSize.
- DataPagePayload data = io.readPayload(pageAddr, itemId(nextLink), pageMem.pageSize());
-
- nextLink = data.nextLink();
-
- if (first) {
- if (nextLink == 0) {
- // Fast path for a single page row.
- return new MetastorageDataRow(link, key, SimpleDataPageIO.readPayload(pageAddr + data.offset()));
- }
-
- first = false;
- }
-
- ByteBuffer buf = pageMem.pageBuffer(pageAddr);
-
- buf.position(data.offset());
- buf.limit(data.offset() + data.payloadSize());
-
- if (size == 0) {
- if (buf.remaining() >= 4 && incomplete == null) {
- // Just read size.
- size = buf.getInt();
- incomplete = new IncompleteObject(new byte[size]);
- }
- else {
- if (incomplete == null)
- incomplete = new IncompleteObject(new byte[4]);
-
- incomplete.readData(buf);
-
- if (incomplete.isReady()) {
- size = ByteBuffer.wrap(incomplete.data()).order(buf.order()).getInt();
- incomplete = new IncompleteObject(new byte[size]);
- }
- }
- }
-
- if (size != 0 && buf.remaining() > 0)
- incomplete.readData(buf);
- }
- finally {
- pageMem.readUnlock(grpId, pageId, page);
- }
- }
- finally {
- pageMem.releasePage(grpId, pageId, page);
- }
- }
- while (nextLink != 0);
-
- assert incomplete.isReady();
-
- return new MetastorageDataRow(link, key, incomplete.data());
- }
- }
-
/**
* Temporary storage internal
*/
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java
index 2d7b0a6..a84924a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageDataRow.java
@@ -17,34 +17,28 @@
package org.apache.ignite.internal.processors.cache.persistence.metastorage;
-import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.pagemem.PageIdAllocator;
-import org.apache.ignite.internal.processors.cache.persistence.Storable;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
/**
*
*/
-public class MetastorageDataRow implements MetastorageSearchRow, Storable {
- /** */
- private long link;
-
+public class MetastorageDataRow extends SimpleDataRow implements MetastorageSearchRow {
/** */
private String key;
/** */
- private byte[] value;
-
- /** */
- public MetastorageDataRow(long link, String key, byte[] value) {
- this.link = link;
+ public MetastorageDataRow(long link, String key, byte[] val) {
+ super(link, MetaStorage.PRESERVE_LEGACY_METASTORAGE_PARTITION_ID ?
+ PageIdAllocator.OLD_METASTORE_PARTITION: PageIdAllocator.METASTORE_PARTITION, val);
this.key = key;
- this.value = value;
}
/** */
- public MetastorageDataRow(String key, byte[] value) {
- this.key = key;
- this.value = value;
+ public MetastorageDataRow(String key, byte[] val) {
+ this(0, key, val);
}
/**
@@ -55,49 +49,17 @@ public class MetastorageDataRow implements MetastorageSearchRow, Storable {
}
/** {@inheritDoc} */
- @Override
- public int hash() {
+ @Override public int hash() {
return key.hashCode();
}
/** {@inheritDoc} */
- @Override
- public int partition() {
- return MetaStorage.PRESERVE_LEGACY_METASTORAGE_PARTITION_ID ? PageIdAllocator.OLD_METASTORE_PARTITION: PageIdAllocator.METASTORE_PARTITION;
- }
-
- /** {@inheritDoc} */
- @Override public int size() throws IgniteCheckedException {
- return 4 + value().length;
- }
-
- /** {@inheritDoc} */
- @Override public int headerSize() {
- return 0;
- }
-
- /** {@inheritDoc} */
- @Override
- public void link(long link) {
- this.link = link;
- }
-
- /** {@inheritDoc} */
- @Override
- public long link() {
- return link;
- }
-
- /**
- * @return Value.
- */
- public byte[] value() {
- return value;
+ @Override public IOVersions<? extends AbstractDataPageIO> ioVersions() {
+ return MetastoreDataPageIO.VERSIONS;
}
/** {@inheritDoc} */
- @Override
- public String toString() {
+ @Override public String toString() {
return "key=" + key;
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageRowStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageRowStore.java
index c482a94..ccc55dc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageRowStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageRowStore.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.processors.cache.persistence.metastorage;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
-import org.apache.ignite.internal.processors.cache.persistence.freelist.FreeList;
+import org.apache.ignite.internal.processors.cache.persistence.partstorage.PartitionMetaStorage;
import org.apache.ignite.internal.stat.IoStatisticsHolderNoOp;
/**
@@ -27,14 +27,14 @@ import org.apache.ignite.internal.stat.IoStatisticsHolderNoOp;
*/
public class MetastorageRowStore {
/** */
- private final FreeList freeList;
+ private final PartitionMetaStorage<MetastorageDataRow> partStorage;
/** */
protected final IgniteCacheDatabaseSharedManager db;
/** */
- public MetastorageRowStore(FreeList freeList, IgniteCacheDatabaseSharedManager db) {
- this.freeList = freeList;
+ public MetastorageRowStore(PartitionMetaStorage<MetastorageDataRow> partStorage, IgniteCacheDatabaseSharedManager db) {
+ this.partStorage = partStorage;
this.db = db;
}
@@ -43,7 +43,7 @@ public class MetastorageRowStore {
* @return Data row.
*/
public MetastorageDataRow dataRow(String key, long link) throws IgniteCheckedException {
- return ((MetaStorage.FreeListImpl)freeList).readRow(key, link);
+ return new MetastorageDataRow(link, key, partStorage.readRow(link));
}
/**
@@ -55,7 +55,7 @@ public class MetastorageRowStore {
db.checkpointReadLock();
try {
- freeList.removeDataRowByLink(link, IoStatisticsHolderNoOp.INSTANCE);
+ partStorage.removeDataRowByLink(link, IoStatisticsHolderNoOp.INSTANCE);
}
finally {
db.checkpointReadUnlock();
@@ -70,28 +70,10 @@ public class MetastorageRowStore {
db.checkpointReadLock();
try {
- freeList.insertDataRow(row, IoStatisticsHolderNoOp.INSTANCE);
+ partStorage.insertDataRow(row, IoStatisticsHolderNoOp.INSTANCE);
}
finally {
db.checkpointReadUnlock();
}
}
-
- /**
- * @param link Row link.
- * @param row New row data.
- * @return {@code True} if was able to update row.
- * @throws IgniteCheckedException If failed.
- */
- public boolean updateRow(long link, MetastorageDataRow row) throws IgniteCheckedException {
- return freeList.updateDataRow(link, row, IoStatisticsHolderNoOp.INSTANCE);
- }
-
- /**
- * @return Free list.
- */
- public FreeList freeList() {
- return freeList;
- }
-
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastoreDataPageIO.java
similarity index 52%
copy from modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
copy to modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastoreDataPageIO.java
index 133f0a1..0ac0915 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastoreDataPageIO.java
@@ -15,38 +15,23 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.persistence;
+package org.apache.ignite.internal.processors.cache.persistence.metastorage;
-import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.SimpleDataPageIO;
/**
- * Simple interface for data, store in some RowStore.
*/
-public interface Storable {
- /**
- * @param link Link for this row.
- */
- public void link(long link);
-
- /**
- * @return Link for this row.
- */
- public long link();
-
- /**
- * @return Partition.
- */
- public int partition();
-
- /**
- * @return Row size in page.
- * @throws IgniteCheckedException If failed.
- */
- public int size() throws IgniteCheckedException;
+public class MetastoreDataPageIO extends SimpleDataPageIO {
+ /** */
+ public static final IOVersions<MetastoreDataPageIO> VERSIONS = new IOVersions<>(
+ new MetastoreDataPageIO(1)
+ );
/**
- * @return Row header size in page. Header is indivisible part of row
- * which is entirely available on the very first page followed by the row link.
+ * @param ver Version.
*/
- public int headerSize();
+ public MetastoreDataPageIO(int ver) {
+ super(T_DATA_METASTORAGE, ver);
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorage.java
similarity index 51%
copy from modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
copy to modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorage.java
index 133f0a1..0dbd5f4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/Storable.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorage.java
@@ -15,38 +15,37 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.processors.cache.persistence;
+package org.apache.ignite.internal.processors.cache.persistence.partstorage;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.persistence.Storable;
+import org.apache.ignite.internal.stat.IoStatisticsHolder;
/**
- * Simple interface for data, store in some RowStore.
+ * Provides a way to associate any {@link Storable} implementation as partition metadata.
*/
-public interface Storable {
+public interface PartitionMetaStorage<T extends Storable> {
/**
- * @param link Link for this row.
- */
- public void link(long link);
-
- /**
- * @return Link for this row.
+ * Read row data by link as byte array.
+ * @param link Link.
+ * @throws IgniteCheckedException If failed.
*/
- public long link();
+ public byte[] readRow(long link) throws IgniteCheckedException;
/**
- * @return Partition.
+ * @param row Row.
+ * @param statHolder Stat holder.
*/
- public int partition();
+ public void insertDataRow(T row, IoStatisticsHolder statHolder) throws IgniteCheckedException;
/**
- * @return Row size in page.
+ * @param link Row link.
* @throws IgniteCheckedException If failed.
*/
- public int size() throws IgniteCheckedException;
+ public void removeDataRowByLink(long link, IoStatisticsHolder statHolder) throws IgniteCheckedException;
/**
- * @return Row header size in page. Header is indivisible part of row
- * which is entirely available on the very first page followed by the row link.
+ * Saves storage metadata.
*/
- public int headerSize();
+ public void saveMetadata() throws IgniteCheckedException;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java
new file mode 100644
index 0000000..f078f2c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.persistence.partstorage;
+
+import java.nio.ByteBuffer;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.PageUtils;
+import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
+import org.apache.ignite.internal.processors.cache.IncompleteObject;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
+import org.apache.ignite.internal.processors.cache.persistence.Storable;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.AbstractFreeList;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.AbstractDataPageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.DataPagePayload;
+import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
+import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
+
+import static org.apache.ignite.internal.pagemem.PageIdUtils.itemId;
+import static org.apache.ignite.internal.pagemem.PageIdUtils.pageId;
+
+/**
+ */
+public class PartitionMetaStorageImpl<T extends Storable> extends AbstractFreeList<T> implements PartitionMetaStorage<T> {
+ /**
+ * @param cacheId Cache id.
+ * @param name Name.
+ * @param memMetrics Mem metrics.
+ * @param memPlc Mem policy.
+ * @param reuseList Reuse list.
+ * @param wal Wal.
+ * @param metaPageId Meta page id.
+ * @param initNew Initialize new.
+ */
+ public PartitionMetaStorageImpl(int cacheId, String name,
+ DataRegionMetricsImpl memMetrics,
+ DataRegion memPlc,
+ ReuseList reuseList,
+ IgniteWriteAheadLogManager wal, long metaPageId, boolean initNew) throws IgniteCheckedException {
+ super(cacheId, name, memMetrics, memPlc, reuseList, wal, metaPageId, initNew);
+ }
+
+ /**
+ * Read row as byte array from data pages.
+ */
+ @Override public final byte[] readRow(long link) throws IgniteCheckedException {
+ assert link != 0 : "link";
+
+ long nextLink = link;
+ IncompleteObject incomplete = null;
+ int size = 0;
+
+ boolean first = true;
+
+ do {
+ final long pageId = pageId(nextLink);
+
+ final long page = pageMem.acquirePage(grpId, pageId);
+
+ try {
+ long pageAddr = pageMem.readLock(grpId, pageId, page); // Non-empty data page must not be recycled.
+
+ assert pageAddr != 0L : nextLink;
+
+ try {
+ AbstractDataPageIO io = PageIO.getPageIO(pageAddr);
+
+ //MetaStorage never encrypted so realPageSize == pageSize.
+ DataPagePayload data = io.readPayload(pageAddr, itemId(nextLink), pageMem.pageSize());
+
+ nextLink = data.nextLink();
+
+ if (first) {
+ if (nextLink == 0) {
+ long payloadAddr = pageAddr + data.offset();
+
+ // Fast path for a single page row.
+ return PageUtils.getBytes(payloadAddr, 4, PageUtils.getInt(payloadAddr, 0));
+ }
+
+ first = false;
+ }
+
+ ByteBuffer buf = pageMem.pageBuffer(pageAddr);
+
+ buf.position(data.offset());
+ buf.limit(data.offset() + data.payloadSize());
+
+ if (size == 0) {
+ if (buf.remaining() >= 4 && incomplete == null) {
+ // Just read size.
+ size = buf.getInt();
+ incomplete = new IncompleteObject(new byte[size]);
+ }
+ else {
+ if (incomplete == null)
+ incomplete = new IncompleteObject(new byte[4]);
+
+ incomplete.readData(buf);
+
+ if (incomplete.isReady()) {
+ size = ByteBuffer.wrap(incomplete.data()).order(buf.order()).getInt();
+ incomplete = new IncompleteObject(new byte[size]);
+ }
+ }
+ }
+
+ if (size != 0 && buf.remaining() > 0)
+ incomplete.readData(buf);
+ }
+ finally {
+ pageMem.readUnlock(grpId, pageId, page);
+ }
+ }
+ finally {
+ pageMem.releasePage(grpId, pageId, page);
+ }
+ }
+ while (nextLink != 0);
+
+ assert incomplete.isReady();
+
+ return incomplete.data();
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
index 54d9816..c131a1e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
@@ -3775,6 +3775,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
break;
case NOOP:
+ case IN_PLACE:
return;
default:
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java
index 78752bb..a2e03e9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/AbstractDataPageIO.java
@@ -39,7 +39,6 @@ import static org.apache.ignite.internal.util.GridUnsafe.bufferAddress;
* Data pages IO.
*/
public abstract class AbstractDataPageIO<T extends Storable> extends PageIO implements CompactablePageIO {
-
/** */
private static final int SHOW_ITEM = 0b0001;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java
index dcf1acd..fafea22 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PageIO.java
@@ -31,6 +31,7 @@ import org.apache.ignite.internal.processors.cache.persistence.IndexStorageImpl;
import org.apache.ignite.internal.processors.cache.persistence.freelist.io.PagesListMetaIO;
import org.apache.ignite.internal.processors.cache.persistence.freelist.io.PagesListNodeIO;
import org.apache.ignite.internal.processors.cache.persistence.metastorage.MetastorageTree;
+import org.apache.ignite.internal.processors.cache.persistence.metastorage.MetastoreDataPageIO;
import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler;
import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener;
import org.apache.ignite.internal.processors.cache.tree.CacheIdAwareDataInnerIO;
@@ -251,6 +252,9 @@ public abstract class PageIO {
/** */
public static final short T_TX_LOG_INNER = 31;
+ /** */
+ public static final short T_DATA_PART = 32;
+
/** Index for payload == 1. */
public static final short T_H2_EX_REF_LEAF_START = 10_000;
@@ -667,6 +671,9 @@ public abstract class PageIO {
return (Q)TrackingPageIO.VERSIONS.forVersion(ver);
case T_DATA_METASTORAGE:
+ return (Q)MetastoreDataPageIO.VERSIONS.forVersion(ver);
+
+ case T_DATA_PART:
return (Q)SimpleDataPageIO.VERSIONS.forVersion(ver);
default:
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIO.java
index 6a81057..c86a64a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIO.java
@@ -194,6 +194,40 @@ public class PagePartitionMetaIO extends PageMetaIO {
"this PagePartitionMetaIO version: ver=" + getVersion());
}
+ /**
+ * @param pageAddr Page address.
+ */
+ public long getPartitionMetaStoreReuseListRoot(long pageAddr) {
+ throw new UnsupportedOperationException("Partition metastore is not supported by " +
+ "this PagePartitionMetaIO version: ver=" + getVersion());
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param listRoot List root.
+ */
+ public void setPartitionMetaStoreReuseListRoot(long pageAddr, long listRoot) {
+ throw new UnsupportedOperationException("Partition metastore is not supported by " +
+ "this PagePartitionMetaIO version: ver=" + getVersion());
+ }
+
+ /**
+ * @param pageAddr Page address.
+ */
+ public long getGapsLink(long pageAddr) {
+ throw new UnsupportedOperationException("Gaps link is not supported by " +
+ "this PagePartitionMetaIO version: ver=" + getVersion());
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param link Link.
+ */
+ public boolean setGapsLink(long pageAddr, long link) {
+ throw new UnsupportedOperationException("Gaps link is not supported by " +
+ "this PagePartitionMetaIO version: ver=" + getVersion());
+ }
+
/** {@inheritDoc} */
@Override protected void printPage(long pageAddr, int pageSize, GridStringBuilder sb) throws IgniteCheckedException {
super.printPage(pageAddr, pageSize, sb);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIOV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIOV2.java
index 220ff83..37b7243 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIOV2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionMetaIOV2.java
@@ -31,6 +31,12 @@ public class PagePartitionMetaIOV2 extends PagePartitionMetaIO {
/** */
private static final int PENDING_TREE_ROOT_OFF = PagePartitionMetaIO.END_OF_PARTITION_PAGE_META;
+ /** */
+ private static final int PART_META_REUSE_LIST_ROOT_OFF = PENDING_TREE_ROOT_OFF + 8;
+
+ /** */
+ private static final int GAPS_LINK = PART_META_REUSE_LIST_ROOT_OFF + 8;
+
/**
* @param ver Version.
*/
@@ -43,6 +49,8 @@ public class PagePartitionMetaIOV2 extends PagePartitionMetaIO {
super.initNewPage(pageAddr, pageId, pageSize);
setPendingTreeRoot(pageAddr, 0L);
+ setPartitionMetaStoreReuseListRoot(pageAddr, 0L);
+ setGapsLink(pageAddr, 0);
}
/** {@inheritDoc} */
@@ -51,8 +59,44 @@ public class PagePartitionMetaIOV2 extends PagePartitionMetaIO {
}
/** {@inheritDoc} */
- @Override public void setPendingTreeRoot(long pageAddr, long treeRoot) {
- PageUtils.putLong(pageAddr, PENDING_TREE_ROOT_OFF, treeRoot);
+ @Override public void setPendingTreeRoot(long pageAddr, long listRoot) {
+ PageUtils.putLong(pageAddr, PENDING_TREE_ROOT_OFF, listRoot);
+ }
+
+ /**
+ * @param pageAddr Page address.
+ */
+ @Override public long getPartitionMetaStoreReuseListRoot(long pageAddr) {
+ return PageUtils.getLong(pageAddr, PART_META_REUSE_LIST_ROOT_OFF);
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param listRoot List root.
+ */
+ @Override public void setPartitionMetaStoreReuseListRoot(long pageAddr, long listRoot) {
+ PageUtils.putLong(pageAddr, PART_META_REUSE_LIST_ROOT_OFF, listRoot);
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @return Partition size.
+ */
+ public long getGapsLink(long pageAddr) {
+ return PageUtils.getLong(pageAddr, GAPS_LINK);
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param link Link.
+ */
+ public boolean setGapsLink(long pageAddr, long link) {
+ if (getGapsLink(pageAddr) == link)
+ return false;
+
+ PageUtils.putLong(pageAddr, GAPS_LINK, link);
+
+ return true;
}
/** {@inheritDoc} */
@@ -72,6 +116,7 @@ public class PagePartitionMetaIOV2 extends PagePartitionMetaIO {
sb.a(",\n\tglobalRemoveId=").a(getGlobalRemoveId(pageAddr));
sb.a(",\n\tpartitionState=").a(state).a("(").a(GridDhtPartitionState.fromOrdinal(state)).a(")");
sb.a(",\n\tcountersPageId=").a(getCountersPageId(pageAddr));
+ sb.a(",\n\tcntrUpdDataPageId=").a(getGapsLink(pageAddr));
sb.a("\n]");
}
@@ -86,5 +131,7 @@ public class PagePartitionMetaIOV2 extends PagePartitionMetaIO {
PageIO.setVersion(pageAddr, getVersion());
setPendingTreeRoot(pageAddr, 0);
+ setPartitionMetaStoreReuseListRoot(pageAddr, 0);
+ setGapsLink(pageAddr, 0);
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/SimpleDataPageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/SimpleDataPageIO.java
index 14489b7..716f8be 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/SimpleDataPageIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/SimpleDataPageIO.java
@@ -20,13 +20,13 @@ package org.apache.ignite.internal.processors.cache.persistence.tree.io;
import java.nio.ByteBuffer;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.pagemem.PageUtils;
-import org.apache.ignite.internal.processors.cache.persistence.metastorage.MetastorageDataRow;
+import org.apache.ignite.internal.processors.cache.persistence.freelist.SimpleDataRow;
import org.apache.ignite.internal.util.GridStringBuilder;
/**
- * Data pages IO for Metastorage.
+ * Data pages IO for writing binary arrays.
*/
-public class SimpleDataPageIO extends AbstractDataPageIO<MetastorageDataRow> {
+public class SimpleDataPageIO extends AbstractDataPageIO<SimpleDataRow> {
/** */
public static final IOVersions<SimpleDataPageIO> VERSIONS = new IOVersions<>(
new SimpleDataPageIO(1)
@@ -36,13 +36,21 @@ public class SimpleDataPageIO extends AbstractDataPageIO<MetastorageDataRow> {
* @param ver Page format version.
*/
public SimpleDataPageIO(int ver) {
- super(T_DATA_METASTORAGE, ver);
+ super(T_DATA_PART, ver);
+ }
+
+ /**
+ * Constructor is intended for extending types.
+ * @param type IO type.
+ * @param ver Page format version.
+ */
+ public SimpleDataPageIO(int type, int ver) {
+ super(type, ver);
}
/** {@inheritDoc} */
- @Override
- protected void writeFragmentData(
- final MetastorageDataRow row,
+ @Override protected void writeFragmentData(
+ final SimpleDataRow row,
final ByteBuffer buf,
final int rowOff,
final int payloadSize
@@ -65,7 +73,7 @@ public class SimpleDataPageIO extends AbstractDataPageIO<MetastorageDataRow> {
}
/** */
- private int writeSizeFragment(final MetastorageDataRow row, final ByteBuffer buf, final int rowOff,
+ private int writeSizeFragment(final SimpleDataRow row, final ByteBuffer buf, final int rowOff,
final int payloadSize) {
final int size = 4;
@@ -89,12 +97,11 @@ public class SimpleDataPageIO extends AbstractDataPageIO<MetastorageDataRow> {
}
/** {@inheritDoc} */
- @Override
- protected void writeRowData(
+ @Override protected void writeRowData(
long pageAddr,
int dataOff,
int payloadSize,
- MetastorageDataRow row,
+ SimpleDataRow row,
boolean newRow
) throws IgniteCheckedException {
long addr = pageAddr + dataOff;
@@ -106,12 +113,6 @@ public class SimpleDataPageIO extends AbstractDataPageIO<MetastorageDataRow> {
PageUtils.putBytes(addr, 6, row.value());
}
- public static byte[] readPayload(long link) {
- int size = PageUtils.getInt(link, 0);
-
- return PageUtils.getBytes(link, 4, size);
- }
-
/** {@inheritDoc} */
@Override protected void printPage(long addr, int pageSize, GridStringBuilder sb) throws IgniteCheckedException {
sb.a("SimpleDataPageIO [\n");
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/util/PageHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/util/PageHandler.java
index 5ab1bf3..ff980af 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/util/PageHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/util/PageHandler.java
@@ -26,6 +26,7 @@ import org.apache.ignite.internal.pagemem.wal.record.delta.InitNewPageRecord;
import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
import org.apache.ignite.internal.stat.IoStatisticsHolder;
import org.apache.ignite.internal.util.GridUnsafe;
+import org.jetbrains.annotations.Nullable;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
@@ -463,7 +464,7 @@ public abstract class PageHandler<X, R> {
long pageId,
long page,
IgniteWriteAheadLogManager wal,
- Boolean walPlc) {
+ @Nullable Boolean walPlc) {
// If the page is clean, then it is either newly allocated or just after checkpoint.
// In both cases we have to write full page contents to WAL.
return wal != null && !wal.isAlwaysWriteFullPages() && walPlc != TRUE && !wal.disabled(cacheId) &&
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
index 86924c6..2831d87 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
@@ -917,7 +917,7 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
if (hnd != null)
end = hnd.position();
- return new RecordsIterator(
+ RecordsIterator iter = new RecordsIterator(
cctx,
walArchiveDir,
walWorkDir,
@@ -932,6 +932,17 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
segmentAware,
segmentRouter,
lockedSegmentFileInputFactory);
+
+ try {
+ iter.init(); // Make sure iterator is closed on any error.
+ }
+ catch (Throwable t) {
+ iter.close();
+
+ throw t;
+ }
+
+ return iter;
}
/** {@inheritDoc} */
@@ -2673,10 +2684,6 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
this.decompressor = decompressor;
this.segmentRouter = segmentRouter;
this.segmentAware = segmentAware;
-
- init();
-
- advance();
}
/** {@inheritDoc} */
@@ -2760,6 +2767,8 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
if (log.isDebugEnabled())
log.debug("Initialized WAL cursor [start=" + start + ", end=" + end + ", curWalSegmIdx=" + curWalSegmIdx + ']');
+
+ advance();
}
/** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/record/RecordTypes.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/record/RecordTypes.java
index 65f0aae..b6d20dc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/record/RecordTypes.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/record/RecordTypes.java
@@ -60,6 +60,7 @@ public final class RecordTypes {
DELTA_TYPE_SET.add(WALRecord.RecordType.PAGES_LIST_REMOVE_PAGE);
DELTA_TYPE_SET.add(WALRecord.RecordType.META_PAGE_INIT);
DELTA_TYPE_SET.add(WALRecord.RecordType.PARTITION_META_PAGE_UPDATE_COUNTERS);
+ DELTA_TYPE_SET.add(WALRecord.RecordType.PARTITION_META_PAGE_UPDATE_COUNTERS_V2);
DELTA_TYPE_SET.add(WALRecord.RecordType.TRACKING_PAGE_DELTA);
DELTA_TYPE_SET.add(WALRecord.RecordType.META_PAGE_UPDATE_LAST_SUCCESSFUL_SNAPSHOT_ID);
DELTA_TYPE_SET.add(WALRecord.RecordType.META_PAGE_UPDATE_LAST_SUCCESSFUL_FULL_SNAPSHOT_ID);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
index 705cc38..ec68972 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV1Serializer.java
@@ -70,6 +70,7 @@ import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdateLastSuc
import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdateLastSuccessfulSnapshotId;
import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdateNextSnapshotId;
import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdatePartitionDataRecord;
+import org.apache.ignite.internal.pagemem.wal.record.delta.MetaPageUpdatePartitionDataRecordV2;
import org.apache.ignite.internal.pagemem.wal.record.delta.NewRootInitRecord;
import org.apache.ignite.internal.pagemem.wal.record.delta.PageListMetaResetCountRecord;
import org.apache.ignite.internal.pagemem.wal.record.delta.PagesListAddPageRecord;
@@ -374,6 +375,10 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
return /*cache ID*/4 + /*page ID*/8 + /*upd cntr*/8 + /*rmv id*/8 + /*part size*/4 + /*counters page id*/8 + /*state*/ 1
+ /*allocatedIdxCandidate*/ 4;
+ case PARTITION_META_PAGE_UPDATE_COUNTERS_V2:
+ return /*cache ID*/4 + /*page ID*/8 + /*upd cntr*/8 + /*rmv id*/8 + /*part size*/4 + /*counters page id*/8 + /*state*/ 1
+ + /*allocatedIdxCandidate*/ 4 + /*link*/ 8;
+
case MEMORY_RECOVERY:
return 8;
@@ -597,17 +602,12 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
break;
case PARTITION_META_PAGE_UPDATE_COUNTERS:
- cacheId = in.readInt();
- pageId = in.readLong();
+ res = new MetaPageUpdatePartitionDataRecord(in);
- long updCntr = in.readLong();
- long rmvId = in.readLong();
- int partSize = in.readInt();
- long countersPageId = in.readLong();
- byte state = in.readByte();
- int allocatedIdxCandidate = in.readInt();
+ break;
- res = new MetaPageUpdatePartitionDataRecord(cacheId, pageId, updCntr, rmvId, partSize, countersPageId, state, allocatedIdxCandidate);
+ case PARTITION_META_PAGE_UPDATE_COUNTERS_V2:
+ res = new MetaPageUpdatePartitionDataRecordV2(in);
break;
@@ -950,7 +950,7 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
int dstIdx = in.readUnsignedShort();
long srcPageId = in.readLong();
int srcIdx = in.readUnsignedShort();
- rmvId = in.readLong();
+ long rmvId = in.readLong();
res = new InnerReplaceRecord<>(cacheId, pageId, dstIdx, srcPageId, srcIdx, rmvId);
@@ -1112,7 +1112,7 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
partId = in.readInt();
- state = in.readByte();
+ byte state = in.readByte();
long updateCntr = in.readLong();
@@ -1201,17 +1201,8 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
break;
case PARTITION_META_PAGE_UPDATE_COUNTERS:
- MetaPageUpdatePartitionDataRecord partDataRec = (MetaPageUpdatePartitionDataRecord)rec;
-
- buf.putInt(partDataRec.groupId());
- buf.putLong(partDataRec.pageId());
-
- buf.putLong(partDataRec.updateCounter());
- buf.putLong(partDataRec.globalRemoveId());
- buf.putInt(partDataRec.partitionSize());
- buf.putLong(partDataRec.countersPageId());
- buf.put(partDataRec.state());
- buf.putInt(partDataRec.allocatedIndexCandidate());
+ case PARTITION_META_PAGE_UPDATE_COUNTERS_V2:
+ ((MetaPageUpdatePartitionDataRecord)rec).toBytes(buf);
break;
@@ -1690,7 +1681,7 @@ public class RecordDataV1Serializer implements RecordDataSerializer {
buf.put(partMetaStateRecord.state());
- buf.putLong(partMetaStateRecord.updateCounter());
+ buf.putLong(0);
break;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
index ec45a06..3063a25 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/serializer/RecordDataV2Serializer.java
@@ -38,6 +38,7 @@ import org.apache.ignite.internal.pagemem.wal.record.MvccDataEntry;
import org.apache.ignite.internal.pagemem.wal.record.MvccDataRecord;
import org.apache.ignite.internal.pagemem.wal.record.MvccTxRecord;
import org.apache.ignite.internal.pagemem.wal.record.PageSnapshot;
+import org.apache.ignite.internal.pagemem.wal.record.RollbackRecord;
import org.apache.ignite.internal.pagemem.wal.record.SnapshotRecord;
import org.apache.ignite.internal.pagemem.wal.record.TxRecord;
import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
@@ -111,6 +112,9 @@ public class RecordDataV2Serializer extends RecordDataV1Serializer {
case MVCC_TX_RECORD:
return txRecordSerializer.size((MvccTxRecord)rec);
+ case ROLLBACK_TX_RECORD:
+ return 4 + 4 + 8 + 8;
+
default:
return super.plainSize(rec);
}
@@ -206,6 +210,14 @@ public class RecordDataV2Serializer extends RecordDataV1Serializer {
case MVCC_TX_RECORD:
return txRecordSerializer.readMvccTx(in);
+ case ROLLBACK_TX_RECORD:
+ int grpId = in.readInt();
+ int partId = in.readInt();
+ long start = in.readLong();
+ long range = in.readLong();
+
+ return new RollbackRecord(grpId, partId, start, range);
+
default:
return super.readPlainRecord(type, in, encrypted, recordSize);
}
@@ -288,6 +300,16 @@ public class RecordDataV2Serializer extends RecordDataV1Serializer {
break;
+ case ROLLBACK_TX_RECORD:
+ RollbackRecord rb = (RollbackRecord)rec;
+
+ buf.putInt(rb.groupId());
+ buf.putInt(rb.partitionId());
+ buf.putLong(rb.start());
+ buf.putLong(rb.range());
+
+ break;
+
default:
super.writePlainRecord(rec, buf);
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEventBuffer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEventBuffer.java
index c707c72..82400f2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEventBuffer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryEventBuffer.java
@@ -114,9 +114,10 @@ public class CacheContinuousQueryEventBuffer {
}
/**
+ * @param backup {@code True} if backup context.
* @return Initial partition counter.
*/
- protected long currentPartitionCounter() {
+ protected long currentPartitionCounter(boolean backup) {
return 0;
}
@@ -153,7 +154,7 @@ public class CacheContinuousQueryEventBuffer {
Object res = null;
for (;;) {
- batch = initBatch(entry.topologyVersion());
+ batch = initBatch(entry.topologyVersion(), backup);
if (batch == null || cntr < batch.startCntr) {
if (backup) {
@@ -185,7 +186,7 @@ public class CacheContinuousQueryEventBuffer {
res = processPending(res, batch, backup);
- batch0 = initBatch(entry.topologyVersion());
+ batch0 = initBatch(entry.topologyVersion(), backup);
}
while (batch != batch0);
}
@@ -195,16 +196,17 @@ public class CacheContinuousQueryEventBuffer {
/**
* @param topVer Current event topology version.
+ * @param backup {@code True} if backup entry.
* @return Current batch.
*/
- @Nullable private Batch initBatch(AffinityTopologyVersion topVer) {
+ private Batch initBatch(AffinityTopologyVersion topVer, boolean backup) {
Batch batch = curBatch.get();
if (batch != null)
return batch;
for (;;) {
- long curCntr = currentPartitionCounter();
+ long curCntr = currentPartitionCounter(backup);
if (curCntr == -1)
return null;
@@ -483,4 +485,4 @@ public class CacheContinuousQueryEventBuffer {
return res;
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
index 7f9b918..d8737bd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
@@ -54,6 +54,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheAffinityManager;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheDeploymentManager;
+import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition;
import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicAbstractUpdateFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition;
import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
@@ -1106,13 +1107,14 @@ public class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler
if (buf == null) {
buf = new CacheContinuousQueryEventBuffer(part) {
- @Override protected long currentPartitionCounter() {
+ @Override protected long currentPartitionCounter(boolean backup) {
GridDhtLocalPartition locPart = cctx.topology().localPartition(part, null, false);
if (locPart == null)
return -1L;
- return locPart.updateCounter();
+ // Use HWM for primary, LWM for backup.
+ return backup ? locPart.updateCounter() : locPart.reservedCounter();
}
};
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
index 7d0f988..a105a2f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
@@ -40,6 +40,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.IgniteExternalizableExpiryPolicy;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.lang.GridAbsClosureX;
import org.apache.ignite.internal.util.lang.GridPeerDeployAware;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -212,6 +213,11 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
/** */
private GridCacheVersion serReadVer;
+ /** */
+ @GridDirectTransient
+ @GridToStringExclude
+ private transient @Nullable GridAbsClosureX cqNotifyC;
+
/**
* Required by {@link Externalizable}
*/
@@ -1262,6 +1268,19 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
key.getClass() : val != null ? val.getClass() : getClass();
}
+ /**
+ */
+ public GridAbsClosureX cqNotifyClosure() {
+ return cqNotifyC;
+ }
+
+ /**
+ * @param clo Clo.
+ */
+ public void cqNotifyClosure(GridAbsClosureX clo) {
+ cqNotifyC = clo;
+ }
+
/** {@inheritDoc} */
@Override public ClassLoader classLoader() {
return deployClass().getClassLoader();
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index 719bf04..787fb97 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.UUID;
import javax.cache.processor.EntryProcessor;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.failure.FailureContext;
@@ -30,6 +31,7 @@ import org.apache.ignite.failure.FailureType;
import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.pagemem.wal.record.RollbackRecord;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection;
import org.apache.ignite.internal.processors.cache.CacheObject;
@@ -1352,8 +1354,14 @@ public class IgniteTxHandler {
if (dhtTx != null)
finish(nodeId, dhtTx, req);
- else
- applyPartitionsUpdatesCounters(req.updateCounters());
+ else {
+ try {
+ applyPartitionsUpdatesCounters(req.updateCounters(), !req.commit(), false);
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
+ }
if (nearTx != null)
finish(nodeId, nearTx, req);
@@ -1422,9 +1430,6 @@ public class IgniteTxHandler {
// Complete remote candidates.
tx.doneRemote(req.baseVersion(), null, null, null);
- tx.setPartitionUpdateCounters(
- req.partUpdateCounters() != null ? req.partUpdateCounters().array() : null);
-
tx.commitRemoteTx();
}
else {
@@ -1698,7 +1703,7 @@ public class IgniteTxHandler {
if (log.isDebugEnabled())
log.debug("Attempt to start a completed transaction (will ignore): " + tx);
- applyPartitionsUpdatesCounters(req.updateCounters());
+ applyPartitionsUpdatesCounters(req.updateCounters(), true, false);
return null;
}
@@ -1710,7 +1715,7 @@ public class IgniteTxHandler {
ctx.tm().uncommitTx(tx);
- applyPartitionsUpdatesCounters(req.updateCounters());
+ applyPartitionsUpdatesCounters(req.updateCounters(), true, false);
return null;
}
@@ -1720,8 +1725,13 @@ public class IgniteTxHandler {
tx.transactionNodes(req.transactionNodes());
}
- if (req.updateCounters() != null)
- tx.txCounters(true).updateCounters(req.updateCounters());
+ TxCounters txCounters = null;
+
+ if (req.updateCounters() != null) {
+ txCounters = tx.txCounters(true);
+
+ txCounters.updateCounters(req.updateCounters());
+ }
if (!tx.isSystemInvalidate()) {
int idx = 0;
@@ -1739,6 +1749,13 @@ public class IgniteTxHandler {
try {
tx.addWrite(entry, ctx.deploy().globalLoader());
+ if (txCounters != null) {
+ Long cntr = txCounters.generateNextCounter(entry.cacheId(), entry.cached().partition());
+
+ if (cntr != null) // Counter is null if entry is no-op.
+ entry.updateCounter(cntr);
+ }
+
if (isNearEnabled(cacheCtx) && req.invalidateNearEntry(idx))
invalidateNearEntry(cacheCtx, entry.key(), req.version());
@@ -2198,7 +2215,12 @@ public class IgniteTxHandler {
* @param req Request.
*/
private void processPartitionCountersRequest(UUID nodeId, PartitionCountersNeighborcastRequest req) {
- applyPartitionsUpdatesCounters(req.updateCounters());
+ try {
+ applyPartitionsUpdatesCounters(req.updateCounters(), true, false);
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException(e);
+ }
try {
ctx.io().send(nodeId, new PartitionCountersNeighborcastResponse(req.futId()), SYSTEM_POOL);
@@ -2230,21 +2252,32 @@ public class IgniteTxHandler {
}
/**
- * Applies partition counter updates for mvcc transactions.
+ * @param counters Counters.
+ */
+ public void applyPartitionsUpdatesCounters(Iterable<PartitionUpdateCountersMessage> counters)
+ throws IgniteCheckedException {
+ applyPartitionsUpdatesCounters(counters, false, false);
+ }
+
+ /**
+ * Applies partition counter updates for transactions.
*
* @param counters Counter values to be updated.
+ * @param rollback {@code True} if applied from rollbacks.
*/
- public void applyPartitionsUpdatesCounters(Iterable<PartitionUpdateCountersMessage> counters) {
+ public void applyPartitionsUpdatesCounters(Iterable<PartitionUpdateCountersMessage> counters,
+ boolean rollback,
+ boolean rollbackOnPrimary) throws IgniteCheckedException {
if (counters == null)
return;
for (PartitionUpdateCountersMessage counter : counters) {
GridCacheContext ctx0 = ctx.cacheContext(counter.cacheId());
- assert ctx0.mvccEnabled();
-
GridDhtPartitionTopology top = ctx0.topology();
+ AffinityTopologyVersion topVer = top.readyTopologyVersion();
+
assert top != null;
for (int i = 0; i < counter.size(); i++) {
@@ -2255,8 +2288,29 @@ public class IgniteTxHandler {
if (part != null && part.reserve()) {
try {
- if (part.state() != GridDhtPartitionState.RENTING)
- part.updateCounter(counter.initialCounter(i), counter.updatesCount(i));
+ if (part.state() != GridDhtPartitionState.RENTING) { // Check is actual only for backup node.
+ long start = counter.initialCounter(i);
+ long delta = counter.updatesCount(i);
+
+ boolean updated = part.updateCounter(start, delta);
+
+ // Need to log rolled back range for logical recovery.
+ if (updated && rollback) {
+ if (part.group().persistenceEnabled() &&
+ part.group().walEnabled() &&
+ !part.group().mvccEnabled()) {
+ RollbackRecord rec = new RollbackRecord(part.group().groupId(), part.id(),
+ start, delta);
+
+ ctx.wal().log(rec);
+ }
+
+ for (int cntr = 1; cntr <= delta; cntr++) {
+ ctx0.continuousQueries().skipUpdateCounter(null, part.id(), start + cntr,
+ topVer, rollbackOnPrimary);
+ }
+ }
+ }
else
invalid = true;
}
@@ -2272,7 +2326,7 @@ public class IgniteTxHandler {
}
if (invalid && log.isDebugEnabled())
- log.debug("Received partition update counters message for invalid partition: " +
+ log.debug("Received partition update counters message for invalid partition, ignoring: " +
"[cacheId=" + counter.cacheId() + ", part=" + counter.partition(i) + "]");
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index 26350b6..55376f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -57,7 +57,6 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.dht.PartitionUpdateCountersMessage;
import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition;
-import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState;
import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
@@ -95,6 +94,8 @@ import static org.apache.ignite.internal.processors.cache.GridCacheOperation.REA
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.RELOAD;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
+import static org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.LOST;
+import static org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.OWNING;
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_PRIMARY;
import static org.apache.ignite.transactions.TransactionState.COMMITTED;
@@ -431,7 +432,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
try {
cctx.tm().prepareTx(this, entries);
- calculatePartitionUpdateCounters();
+ if (txState().mvccEnabled())
+ calculatePartitionUpdateCounters();
}
catch (IgniteCheckedException e) {
throw e;
@@ -451,7 +453,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
* pair (init, delta) values, where init - initial update counter, and delta - updates count made
* by current transaction for a given partition.
*/
- private void calculatePartitionUpdateCounters() {
+ public void calculatePartitionUpdateCounters() {
TxCounters counters = txCounters(false);
if (counters != null && F.isEmpty(counters.updateCounters())) {
@@ -468,9 +470,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
continue;
PartitionUpdateCountersMessage msg = new PartitionUpdateCountersMessage(cacheId, partToCntrs.size());
- GridCacheContext ctx0 = cctx.cacheContext(cacheId);
- assert ctx0 != null && ctx0.mvccEnabled();
+ GridCacheContext ctx0 = cctx.cacheContext(cacheId);
GridDhtPartitionTopology top = ctx0.topology();
@@ -490,7 +491,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
GridDhtLocalPartition part = top.localPartition(p);
- assert part != null && part.state() == GridDhtPartitionState.OWNING;
+ // LOST state is possible if tx is started over LOST partition.
+ assert part != null && (part.state() == OWNING || part.state() == LOST):
+ part == null ?
+ "map=" + top.partitionMap(false) + ", lost=" + top.lostPartitions() :
+ "part=" + part.toString();
msg.add(p, part.getAndIncrementUpdateCounter(cntr), cntr);
}
@@ -577,6 +582,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
AffinityTopologyVersion topVer = topologyVersion();
+ TxCounters txCounters = txCounters(false);
+
/*
* Commit to cache. Note that for 'near' transaction we loop through all the entries.
*/
@@ -893,7 +900,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
txEntry.cached(entryEx(cacheCtx, txEntry.txKey(), topologyVersion()));
}
}
+ }
+
+ if (!txState.mvccEnabled() && txCounters != null) {
+ cctx.tm().txHandler().applyPartitionsUpdatesCounters(txCounters.updateCounters());
+ for (IgniteTxEntry entry : commitEntries) {
+ if (entry.cqNotifyClosure() != null)
+ entry.cqNotifyClosure().applyx();
+ }
}
// Apply cache sizes only for primary nodes. Update counters were applied on prepare state.
@@ -1072,6 +1087,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter implements Ig
}
if (DONE_FLAG_UPD.compareAndSet(this, 0, 1)) {
+ if (!txState.mvccEnabled()) {
+ TxCounters txCounters = txCounters(false);
+
+ if (txCounters != null)
+ cctx.tm().txHandler().applyPartitionsUpdatesCounters(txCounters.updateCounters(), true, true);
+ }
+
cctx.tm().rollbackTx(this, clearThreadMap, skipCompletedVersions());
cctx.mvccCaching().onTxFinished(this, false);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index c88c863..6f2d594 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -2128,8 +2128,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (commit)
tx.commitAsync().listen(new CommitListener(tx));
- else if (tx.mvccSnapshot() != null && !tx.local())
- // remote (backup) mvcc transaction sends partition counters to other backup transaction
+ else if (!tx.local())
+ // remote (backup) transaction sends partition counters to other backup transaction on recovery rollback
// in order to keep counters consistent
neighborcastPartitionCountersAndRollback(tx);
else
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxCounters.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxCounters.java
index 515aeef..15c92f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxCounters.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxCounters.java
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.internal.processors.cache.distributed.dht.PartitionUpdateCountersMessage;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
/**
@@ -37,7 +38,7 @@ public class TxCounters {
private final Map<Integer, Map<Integer, AtomicLong>> updCntrsAcc = new HashMap<>();
/** Final update counters for cache partitions in the end of transaction */
- private volatile Collection<PartitionUpdateCountersMessage> updCntrs;
+ private volatile Map<Integer, PartitionUpdateCountersMessage> updCntrs;
/** Counter tracking number of entries locked by tx. */
private final AtomicInteger lockCntr = new AtomicInteger();
@@ -68,14 +69,17 @@ public class TxCounters {
* @param updCntrs Final update counters.
*/
public void updateCounters(Collection<PartitionUpdateCountersMessage> updCntrs) {
- this.updCntrs = updCntrs;
+ this.updCntrs = U.newHashMap(updCntrs.size());
+
+ for (PartitionUpdateCountersMessage cntr : updCntrs)
+ this.updCntrs.put(cntr.cacheId(), cntr);
}
/**
* @return Final update counters.
*/
@Nullable public Collection<PartitionUpdateCountersMessage> updateCounters() {
- return updCntrs;
+ return updCntrs == null ? null : updCntrs.values();
}
/**
@@ -145,4 +149,19 @@ public class TxCounters {
public int lockCounter() {
return lockCntr.get();
}
+
+ /**
+ * @param cacheId Cache id.
+ * @param partId Partition id.
+ *
+ * @return Counter or {@code null} if cache partition has not updates.
+ */
+ public Long generateNextCounter(int cacheId, int partId) {
+ PartitionUpdateCountersMessage msg = updCntrs.get(cacheId);
+
+ if (msg == null)
+ return null;
+
+ return msg.nextCounter(partId);
+ }
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
index f05e0e5..17d4be0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
@@ -44,6 +44,7 @@ import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteFeatures;
import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.NodeStoppingException;
import org.apache.ignite.internal.cluster.ClusterGroupAdapter;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.cluster.DistributedBaselineConfiguration;
@@ -385,7 +386,7 @@ public class GridClusterStateProcessor extends GridProcessorAdapter implements I
GridChangeGlobalStateFuture fut = this.stateChangeFut.get();
if (fut != null)
- fut.onDone(new IgniteCheckedException("Failed to wait for cluster state change, node is stopping."));
+ fut.onDone(new NodeStoppingException("Failed to wait for cluster state change, node is stopping."));
super.onKernalStop(cancel);
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/stat/IoStatisticsHolder.java b/modules/core/src/main/java/org/apache/ignite/internal/stat/IoStatisticsHolder.java
index 0c36820..5b7a57f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/stat/IoStatisticsHolder.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/stat/IoStatisticsHolder.java
@@ -24,7 +24,6 @@ import java.util.Map;
* Holder of IO statistics.
*/
public interface IoStatisticsHolder {
-
/**
* Track logical read of given page.
*
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java
index 9e854d2..140349a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java
@@ -141,6 +141,9 @@ public interface IgniteTree<L, T> {
REMOVE,
/** */
- PUT
+ PUT,
+
+ /** */
+ IN_PLACE
}
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 395705c..5d9d8da 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -9519,6 +9519,60 @@ public abstract class IgniteUtils {
}
/**
+ * Create a map with single key-value pair.
+ *
+ * @param k Key.
+ * @param v Value.
+ * @return Map.
+ */
+ public static <K, V> Map<K, V> map(K k, V v) {
+ GridLeanMap<K, V> map = new GridLeanMap<>(1);
+
+ map.put(k, v);
+
+ return map;
+ }
+
+ /**
+ * Create a map with two key-value pairs.
+ *
+ * @param k1 Key 1.
+ * @param v1 Value 1.
+ * @param k2 Key 2.
+ * @param v2 Value 2.
+ * @return Map.
+ */
+ public static <K, V> Map<K, V> map(K k1, V v1, K k2, V v2) {
+ GridLeanMap<K, V> map = new GridLeanMap<>(2);
+
+ map.put(k1, v1);
+ map.put(k2, v2);
+
+ return map;
+ }
+
+ /**
+ * Create a map with three key-value pairs.
+ *
+ * @param k1 Key 1.
+ * @param v1 Value 1.
+ * @param k2 Key 2.
+ * @param v2 Value 2.
+ * @param k3 Key 3.
+ * @param v3 Value 3.
+ * @return Map.
+ */
+ public static <K, V> Map<K, V> map(K k1, V v1, K k2, V v2, K k3, V v3) {
+ GridLeanMap<K, V> map = new GridLeanMap<>(3);
+
+ map.put(k1, v1);
+ map.put(k2, v2);
+ map.put(k3, v3);
+
+ return map;
+ }
+
+ /**
* @param col non-null collection with one element
* @return a SingletonList containing the element in the original collection
*/
@@ -9699,7 +9753,7 @@ public abstract class IgniteUtils {
public static <T extends R, R> List<R> arrayList(Collection<T> c, @Nullable IgnitePredicate<? super T>... p) {
assert c != null;
- return arrayList(c, c.size(), p);
+ return arrayList(c.iterator(), c.size(), p);
}
/**
@@ -9718,14 +9772,16 @@ public abstract class IgniteUtils {
* @param p Optional filters.
* @return Resulting array list.
*/
- public static <T extends R, R> List<R> arrayList(Iterable<T> c, int cap,
+ public static <T extends R, R> List<R> arrayList(Iterator<T> c, int cap,
@Nullable IgnitePredicate<? super T>... p) {
assert c != null;
assert cap >= 0;
List<R> list = new ArrayList<>(cap);
- for (T t : c) {
+ while (c.hasNext()) {
+ T t = c.next();
+
if (F.isAll(t, p))
list.add(t);
}
diff --git a/modules/core/src/test/config/log4j-test.xml b/modules/core/src/test/config/log4j-test.xml
index bb5f94a..7206b4e 100755
--- a/modules/core/src/test/config/log4j-test.xml
+++ b/modules/core/src/test/config/log4j-test.xml
@@ -97,6 +97,15 @@
</category>
-->
+ <!--
+ Uncomment to enable debugging of partition counters.
+ -->
+ <!--
+ <category name="org.apache.ignite.internal.processors.cache.PartitionTxUpdateCounterDebugWrapper">
+ <level value="DEBUG"/>
+ </category>
+ -->
+
<!-- Disable all open source debugging. -->
<category name="org">
<level value="INFO"/>
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/ResetLostPartitionTest.java b/modules/core/src/test/java/org/apache/ignite/cache/ResetLostPartitionTest.java
index 8d318dc..3e1568a 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/ResetLostPartitionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/ResetLostPartitionTest.java
@@ -36,6 +36,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
+import static org.apache.ignite.configuration.WALMode.LOG_ONLY;
import static org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.LOST;
import static org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState.OWNING;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR;
@@ -75,6 +76,8 @@ public class ResetLostPartitionTest extends GridCommonAbstractTest {
DataStorageConfiguration storageCfg = new DataStorageConfiguration();
+ storageCfg.setPageSize(1024).setWalMode(LOG_ONLY).setWalSegmentSize(8 * 1024 * 1024);
+
storageCfg.getDefaultDataRegionConfiguration()
.setPersistenceEnabled(true)
.setMaxSize(500L * 1024 * 1024);
@@ -104,7 +107,7 @@ public class ResetLostPartitionTest extends GridCommonAbstractTest {
.setBackups(1)
.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
.setPartitionLossPolicy(PartitionLossPolicy.READ_ONLY_SAFE)
- .setAffinity(new RendezvousAffinityFunction(false, 1024))
+ .setAffinity(new RendezvousAffinityFunction(false, 64))
.setIndexedTypes(String.class, String.class);
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/TestRecordingCommunicationSpi.java b/modules/core/src/test/java/org/apache/ignite/internal/TestRecordingCommunicationSpi.java
index 988395f..5969d25 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/TestRecordingCommunicationSpi.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/TestRecordingCommunicationSpi.java
@@ -18,10 +18,10 @@
package org.apache.ignite.internal;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,7 +30,7 @@ import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.managers.communication.GridIoMessage;
-import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiInClosure;
@@ -300,7 +300,7 @@ public class TestRecordingCommunicationSpi extends TcpCommunicationSpi {
* Stops block messages and sends all already blocked messages.
*/
public void stopBlock() {
- stopBlock(true, null);
+ stopBlock(true, null, true, true);
}
/**
@@ -309,7 +309,7 @@ public class TestRecordingCommunicationSpi extends TcpCommunicationSpi {
* @param sndMsgs {@code True} to send blocked messages.
*/
public void stopBlock(boolean sndMsgs) {
- stopBlock(sndMsgs, null);
+ stopBlock(sndMsgs, null, true, true);
}
/**
@@ -320,15 +320,37 @@ public class TestRecordingCommunicationSpi extends TcpCommunicationSpi {
* @param unblockPred If not null unblocks only messages allowed by predicate.
*/
public void stopBlock(boolean sndMsgs, @Nullable IgnitePredicate<T2<ClusterNode, GridIoMessage>> unblockPred) {
+ stopBlock(sndMsgs, unblockPred, true, true);
+ }
+
+ /**
+ * Stops block messages and sends all already blocked messages if sndMsgs is 'true' optionally filtered by
+ * unblockPred.
+ *
+ * @param sndMsgs If {@code true} sends blocked messages.
+ * @param unblockPred If not null unblocks only messages allowed by predicate.
+ * @param clearFilters {@code true} to clear filters.
+ * @param rmvBlockedMsgs {@code true} to remove blocked messages. Sometimes useful in conjunction with {@code
+ * sndMsgs=false}.
+ */
+ public void stopBlock(boolean sndMsgs, @Nullable IgnitePredicate<T2<ClusterNode, GridIoMessage>> unblockPred,
+ boolean clearFilters, boolean rmvBlockedMsgs) {
synchronized (this) {
- blockCls.clear();
- blockP = null;
+ if (clearFilters) {
+ blockCls.clear();
+ blockP = null;
+ }
- Collection<T2<ClusterNode, GridIoMessage>> msgs =
- unblockPred == null ? blockedMsgs : F.view(blockedMsgs, unblockPred);
+ Iterator<T2<ClusterNode, GridIoMessage>> iter = blockedMsgs.iterator();
- if (sndMsgs) {
- for (T2<ClusterNode, GridIoMessage> msg : msgs) {
+ while (iter.hasNext()) {
+ T2<ClusterNode, GridIoMessage> msg = iter.next();
+
+ // It is important what predicate if called only once for each message.
+ if (unblockPred != null && !unblockPred.apply(msg))
+ continue;
+
+ if (sndMsgs) {
try {
ignite.log().info("Send blocked message [node=" + msg.get1().id() +
", order=" + msg.get1().order() +
@@ -340,9 +362,18 @@ public class TestRecordingCommunicationSpi extends TcpCommunicationSpi {
U.error(ignite.log(), "Failed to send blocked message: " + msg, e);
}
}
- }
- msgs.clear();
+ if (rmvBlockedMsgs)
+ iter.remove();
+ }
}
}
+
+ /**
+ * Stop blocking all messages.
+ */
+ public static void stopBlockAll() {
+ for (Ignite ignite : G.allGrids())
+ spi(ignite).stopBlock(true);
+ }
}
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGroupsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGroupsTest.java
index 222b161..2f02e10 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGroupsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGroupsTest.java
@@ -115,7 +115,8 @@ import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_REA
import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
/**
- *
+ * TODO FIXME Mixed atomic-tx cache groups currently are broken if tx cache is dynamically started after atomic.
+ * TODO FIXME See https://issues.apache.org/jira/browse/IGNITE-11797
*/
@SuppressWarnings({"unchecked", "ThrowableNotThrown"})
public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
@@ -2291,7 +2292,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
for (final int i : sequence(loaders)) {
final IgniteDataStreamer ldr = clientNode.dataStreamer(cache.getName());
-
+ ldr.allowOverwrite(true); // TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11793
ldr.autoFlushFrequency(0);
cls.add(new Callable<Void>() {
@@ -2985,6 +2986,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
}
/**
+ * TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11797
* @throws Exception If failed.
*/
@Test
@@ -3090,6 +3092,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
}
/**
+ * TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11797
* @throws Exception If failed.
*/
@Test
@@ -3196,7 +3199,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
IgniteCache cache = node.createCache(cacheConfiguration(grp, "tmpCache-" + cntr++,
PARTITIONED,
- rnd.nextBoolean() ? ATOMIC : TRANSACTIONAL,
+ grp.equals(GROUP1) ? ATOMIC : TRANSACTIONAL,
backups,
rnd.nextBoolean()));
@@ -3816,6 +3819,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
}
/**
+ * TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11797
* @throws Exception If failed.
*/
@Test
@@ -3824,6 +3828,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
}
/**
+ * TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11797
* @throws Exception If failed.
*/
@Test
@@ -3846,8 +3851,8 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
client.createCache(cacheConfiguration(GROUP1, "c2", PARTITIONED, TRANSACTIONAL, 1, false));
client.createCache(cacheConfiguration(GROUP1, "c3", PARTITIONED, ATOMIC, 1, false));
- client.createCache(cacheConfiguration(GROUP2, "c4", PARTITIONED, TRANSACTIONAL, 1, false));
- client.createCache(cacheConfiguration(GROUP2, "c5", PARTITIONED, ATOMIC, 1, false));
+ client.createCache(cacheConfiguration(GROUP2, "c4", PARTITIONED, ATOMIC, 1, false));
+ client.createCache(cacheConfiguration(GROUP2, "c5", PARTITIONED, TRANSACTIONAL, 1, false));
client.createCache(cacheConfiguration(GROUP2, "c6", PARTITIONED, TRANSACTIONAL, 1, false));
client.createCache(cacheConfiguration(null, "c7", PARTITIONED, ATOMIC, 1, false));
@@ -3946,6 +3951,7 @@ public class IgniteCacheGroupsTest extends GridCommonAbstractTest {
}
/**
+ * TODO FIXME https://issues.apache.org/jira/browse/IGNITE-11797
* @throws Exception If failed.
*/
@Test
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossDetectionOnNodeLeftTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossDetectionOnNodeLeftTest.java
new file mode 100644
index 0000000..61b024c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePartitionLossDetectionOnNodeLeftTest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.CacheRebalancingEvent;
+import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.PartitionLossPolicy.IGNORE;
+import static org.apache.ignite.testframework.GridTestUtils.mergeExchangeWaitVersion;
+
+/**
+ * Tests if lost partitions are same on left nodes after other owners removal.
+ */
+@RunWith(JUnit4.class)
+public class CachePartitionLossDetectionOnNodeLeftTest extends GridCommonAbstractTest {
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setConsistentId(igniteInstanceName);
+
+ cfg.setCacheConfiguration(new CacheConfiguration(DEFAULT_CACHE_NAME).
+ setAtomicityMode(TRANSACTIONAL).
+ setCacheMode(PARTITIONED).
+ setPartitionLossPolicy(IGNORE). // If default will ever change...
+ setBackups(0));
+
+ return cfg;
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testPartitionLossDetectionOnNodeLeft() throws Exception {
+ try {
+ final Ignite srv0 = startGrids(5);
+
+ List<Integer> lost0 = Collections.synchronizedList(new ArrayList<>());
+ List<Integer> lost1 = Collections.synchronizedList(new ArrayList<>());
+
+ grid(0).events().localListen(evt -> {
+ lost0.add(((CacheRebalancingEvent)evt).partition());
+
+ return true;
+ }, EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST);
+
+ grid(1).events().localListen(evt -> {
+ lost1.add(((CacheRebalancingEvent)evt).partition());
+
+ return true;
+ }, EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST);
+
+ awaitPartitionMapExchange();
+
... 6200 lines suppressed ...