mirror of https://github.com/apache/cassandra
Remove Windows-specific classes and related code
patch by Stefan Miklosovic; reviewed by Joshua McKenzie, Bowen Song, Berenguer Blasi for CASSANDRA-16956
This commit is contained in:
parent
28eea6e8cd
commit
da47849b50
|
|
@ -223,9 +223,6 @@
|
||||||
<url url="${lib.download.base.url}/lib/sigar-bin/libsigar-x86-freebsd-6.so"/>
|
<url url="${lib.download.base.url}/lib/sigar-bin/libsigar-x86-freebsd-6.so"/>
|
||||||
<url url="${lib.download.base.url}/lib/sigar-bin/libsigar-x86-linux.so"/>
|
<url url="${lib.download.base.url}/lib/sigar-bin/libsigar-x86-linux.so"/>
|
||||||
<url url="${lib.download.base.url}/lib/sigar-bin/libsigar-x86-solaris.so"/>
|
<url url="${lib.download.base.url}/lib/sigar-bin/libsigar-x86-solaris.so"/>
|
||||||
<url url="${lib.download.base.url}/lib/sigar-bin/sigar-amd64-winnt.dll"/>
|
|
||||||
<url url="${lib.download.base.url}/lib/sigar-bin/sigar-x86-winnt.dll"/>
|
|
||||||
<url url="${lib.download.base.url}/lib/sigar-bin/sigar-x86-winnt.lib"/>
|
|
||||||
</get>
|
</get>
|
||||||
|
|
||||||
<copy todir="${build.lib}" quiet="true">
|
<copy todir="${build.lib}" quiet="true">
|
||||||
|
|
@ -254,9 +251,6 @@
|
||||||
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/libsigar-x86-freebsd-6.so"/>
|
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/libsigar-x86-freebsd-6.so"/>
|
||||||
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/libsigar-x86-linux.so"/>
|
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/libsigar-x86-linux.so"/>
|
||||||
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/libsigar-x86-solaris.so"/>
|
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/libsigar-x86-solaris.so"/>
|
||||||
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/sigar-amd64-winnt.dll"/>
|
|
||||||
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/sigar-x86-winnt.dll"/>
|
|
||||||
<file file="${local.repository}/org/apache/cassandra/deps/sigar-bin/sigar-x86-winnt.lib"/>
|
|
||||||
</copy>
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
4.1
|
4.1
|
||||||
|
* Remove support for Windows (CASSANDRA-16956)
|
||||||
* Runtime-configurable YAML option to prohibit USE statements (CASSANDRA-17318)
|
* Runtime-configurable YAML option to prohibit USE statements (CASSANDRA-17318)
|
||||||
* When streaming sees a ClosedChannelException this triggers the disk failure policy (CASSANDRA-17116)
|
* When streaming sees a ClosedChannelException this triggers the disk failure policy (CASSANDRA-17116)
|
||||||
* Add a virtual table for exposing prepared statements metrics (CASSANDRA-17224)
|
* Add a virtual table for exposing prepared statements metrics (CASSANDRA-17224)
|
||||||
|
|
|
||||||
|
|
@ -119,14 +119,6 @@ if [ -z "$CASSANDRA_LOG_DIR" ]; then
|
||||||
CASSANDRA_LOG_DIR=$CASSANDRA_HOME/logs
|
CASSANDRA_LOG_DIR=$CASSANDRA_HOME/logs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Special-case path variables.
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN*|MINGW*)
|
|
||||||
CLASSPATH=`cygpath -p -w "$CLASSPATH"`
|
|
||||||
CASSANDRA_CONF=`cygpath -p -w "$CASSANDRA_CONF"`
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Cassandra uses an installed jemalloc via LD_PRELOAD / DYLD_INSERT_LIBRARIES by default to improve off-heap
|
# Cassandra uses an installed jemalloc via LD_PRELOAD / DYLD_INSERT_LIBRARIES by default to improve off-heap
|
||||||
# memory allocation performance. The following code searches for an installed libjemalloc.dylib/.so/.1.so using
|
# memory allocation performance. The following code searches for an installed libjemalloc.dylib/.so/.1.so using
|
||||||
# Linux and OS-X specific approaches.
|
# Linux and OS-X specific approaches.
|
||||||
|
|
|
||||||
48
bin/cqlsh.py
48
bin/cqlsh.py
|
|
@ -28,6 +28,7 @@ import os
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
import stat
|
import stat
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import warnings
|
import warnings
|
||||||
|
|
@ -44,7 +45,6 @@ if platform.python_implementation().startswith('Jython'):
|
||||||
sys.exit("\nCQL Shell does not run on Jython\n")
|
sys.exit("\nCQL Shell does not run on Jython\n")
|
||||||
|
|
||||||
UTF8 = 'utf-8'
|
UTF8 = 'utf-8'
|
||||||
CP65001 = 'cp65001' # Win utf-8 variant
|
|
||||||
|
|
||||||
description = "CQL Shell for Apache Cassandra"
|
description = "CQL Shell for Apache Cassandra"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
|
|
@ -92,14 +92,8 @@ if webbrowser._tryorder and webbrowser._tryorder[0] == 'xdg-open' and os.environ
|
||||||
# use bundled lib for python-cql if available. if there
|
# use bundled lib for python-cql if available. if there
|
||||||
# is a ../lib dir, use bundled libs there preferentially.
|
# is a ../lib dir, use bundled libs there preferentially.
|
||||||
ZIPLIB_DIRS = [os.path.join(CASSANDRA_PATH, 'lib')]
|
ZIPLIB_DIRS = [os.path.join(CASSANDRA_PATH, 'lib')]
|
||||||
myplatform = platform.system()
|
|
||||||
is_win = myplatform == 'Windows'
|
|
||||||
|
|
||||||
# Workaround for supporting CP65001 encoding on python < 3.3 (https://bugs.python.org/issue13216)
|
if platform.system() == 'Linux':
|
||||||
if is_win and sys.version_info < (3, 3):
|
|
||||||
codecs.register(lambda name: codecs.lookup(UTF8) if name == CP65001 else None)
|
|
||||||
|
|
||||||
if myplatform == 'Linux':
|
|
||||||
ZIPLIB_DIRS.append('/usr/share/cassandra/lib')
|
ZIPLIB_DIRS.append('/usr/share/cassandra/lib')
|
||||||
|
|
||||||
if os.environ.get('CQLSH_NO_BUNDLED', ''):
|
if os.environ.get('CQLSH_NO_BUNDLED', ''):
|
||||||
|
|
@ -211,7 +205,7 @@ parser.add_option('--debug', action='store_true',
|
||||||
parser.add_option('--coverage', action='store_true',
|
parser.add_option('--coverage', action='store_true',
|
||||||
help='Collect coverage data')
|
help='Collect coverage data')
|
||||||
parser.add_option("--encoding", help="Specify a non-default encoding for output."
|
parser.add_option("--encoding", help="Specify a non-default encoding for output."
|
||||||
" (Default: %s)" % (UTF8,))
|
+ " (Default: %s)" % (UTF8,))
|
||||||
parser.add_option("--cqlshrc", help="Specify an alternative cqlshrc file location.")
|
parser.add_option("--cqlshrc", help="Specify an alternative cqlshrc file location.")
|
||||||
parser.add_option("--credentials", help="Specify an alternative credentials file location.")
|
parser.add_option("--credentials", help="Specify an alternative credentials file location.")
|
||||||
parser.add_option('--cqlversion', default=None,
|
parser.add_option('--cqlversion', default=None,
|
||||||
|
|
@ -261,9 +255,9 @@ OLD_CONFIG_FILE = os.path.expanduser(os.path.join('~', '.cqlshrc'))
|
||||||
if os.path.exists(OLD_CONFIG_FILE):
|
if os.path.exists(OLD_CONFIG_FILE):
|
||||||
if os.path.exists(CONFIG_FILE):
|
if os.path.exists(CONFIG_FILE):
|
||||||
print('\nWarning: cqlshrc config files were found at both the old location ({0})'
|
print('\nWarning: cqlshrc config files were found at both the old location ({0})'
|
||||||
' and the new location ({1}), the old config file will not be migrated to the new'
|
+ ' and the new location ({1}), the old config file will not be migrated to the new'
|
||||||
' location, and the new location will be used for now. You should manually'
|
+ ' location, and the new location will be used for now. You should manually'
|
||||||
' consolidate the config files at the new location and remove the old file.'
|
+ ' consolidate the config files at the new location and remove the old file.'
|
||||||
.format(OLD_CONFIG_FILE, CONFIG_FILE))
|
.format(OLD_CONFIG_FILE, CONFIG_FILE))
|
||||||
else:
|
else:
|
||||||
os.rename(OLD_CONFIG_FILE, CONFIG_FILE)
|
os.rename(OLD_CONFIG_FILE, CONFIG_FILE)
|
||||||
|
|
@ -508,7 +502,6 @@ class Shell(cmd.Cmd):
|
||||||
|
|
||||||
self.tty = tty
|
self.tty = tty
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
self.check_windows_encoding()
|
|
||||||
|
|
||||||
self.output_codec = codecs.lookup(encoding)
|
self.output_codec = codecs.lookup(encoding)
|
||||||
|
|
||||||
|
|
@ -543,15 +536,7 @@ class Shell(cmd.Cmd):
|
||||||
@property
|
@property
|
||||||
def is_using_utf8(self):
|
def is_using_utf8(self):
|
||||||
# utf8 encodings from https://docs.python.org/{2,3}/library/codecs.html
|
# utf8 encodings from https://docs.python.org/{2,3}/library/codecs.html
|
||||||
return self.encoding.replace('-', '_').lower() in ['utf', 'utf_8', 'u8', 'utf8', CP65001]
|
return self.encoding.replace('-', '_').lower() in ['utf', 'utf_8', 'u8', 'utf8']
|
||||||
|
|
||||||
def check_windows_encoding(self):
|
|
||||||
if is_win and os.name == 'nt' and self.tty and \
|
|
||||||
self.is_using_utf8 and sys.stdout.encoding != CP65001:
|
|
||||||
self.printerr("\nWARNING: console codepage must be set to cp65001 "
|
|
||||||
"to support {} encoding on Windows platforms.\n"
|
|
||||||
"If you experience encoding problems, change your console"
|
|
||||||
" codepage with 'chcp 65001' before starting cqlsh.\n".format(self.encoding))
|
|
||||||
|
|
||||||
def set_expanded_cql_version(self, ver):
|
def set_expanded_cql_version(self, ver):
|
||||||
ver, vertuple = full_cql_version(ver)
|
ver, vertuple = full_cql_version(ver)
|
||||||
|
|
@ -817,8 +802,6 @@ class Shell(cmd.Cmd):
|
||||||
try:
|
try:
|
||||||
import readline
|
import readline
|
||||||
except ImportError:
|
except ImportError:
|
||||||
if is_win:
|
|
||||||
print("WARNING: pyreadline dependency missing. Install to enable tab completion.")
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
old_completer = readline.get_completer()
|
old_completer = readline.get_completer()
|
||||||
|
|
@ -1886,8 +1869,7 @@ class Shell(cmd.Cmd):
|
||||||
|
|
||||||
Clears the console.
|
Clears the console.
|
||||||
"""
|
"""
|
||||||
import subprocess
|
subprocess.call('clear', shell=True)
|
||||||
subprocess.call(['clear', 'cls'][is_win], shell=True)
|
|
||||||
do_cls = do_clear
|
do_cls = do_clear
|
||||||
|
|
||||||
def do_debug(self, parsed):
|
def do_debug(self, parsed):
|
||||||
|
|
@ -2098,7 +2080,6 @@ def should_use_color():
|
||||||
if os.environ.get('TERM', '') in ('dumb', ''):
|
if os.environ.get('TERM', '') in ('dumb', ''):
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
import subprocess
|
|
||||||
p = subprocess.Popen(['tput', 'colors'], stdout=subprocess.PIPE)
|
p = subprocess.Popen(['tput', 'colors'], stdout=subprocess.PIPE)
|
||||||
stdout, _ = p.communicate()
|
stdout, _ = p.communicate()
|
||||||
if int(stdout.strip()) < 8:
|
if int(stdout.strip()) < 8:
|
||||||
|
|
@ -2111,11 +2092,6 @@ def should_use_color():
|
||||||
|
|
||||||
|
|
||||||
def is_file_secure(filename):
|
def is_file_secure(filename):
|
||||||
if is_win:
|
|
||||||
# We simply cannot tell whether the file is seucre on Windows,
|
|
||||||
# because os.stat().st_uid is always 0 and os.stat().st_mode is meaningless
|
|
||||||
return True
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
st = os.stat(filename)
|
st = os.stat(filename)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
|
@ -2359,9 +2335,9 @@ def main(options, hostname, port):
|
||||||
# does contain a TZ part) was specified
|
# does contain a TZ part) was specified
|
||||||
if options.time_format != DEFAULT_TIMESTAMP_FORMAT:
|
if options.time_format != DEFAULT_TIMESTAMP_FORMAT:
|
||||||
sys.stderr.write("Warning: custom timestamp format specified in cqlshrc, "
|
sys.stderr.write("Warning: custom timestamp format specified in cqlshrc, "
|
||||||
"but local timezone could not be detected.\n"
|
+ "but local timezone could not be detected.\n"
|
||||||
"Either install Python 'tzlocal' module for auto-detection "
|
+ "Either install Python 'tzlocal' module for auto-detection "
|
||||||
"or specify client timezone in your cqlshrc.\n\n")
|
+ "or specify client timezone in your cqlshrc.\n\n")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shell = Shell(hostname,
|
shell = Shell(hostname,
|
||||||
|
|
@ -2414,7 +2390,7 @@ def main(options, hostname, port):
|
||||||
|
|
||||||
|
|
||||||
# always call this regardless of module name: when a sub-process is spawned
|
# always call this regardless of module name: when a sub-process is spawned
|
||||||
# on Windows then the module name is not __main__, see CASSANDRA-9304
|
# on Windows then the module name is not __main__, see CASSANDRA-9304 (Windows support was dropped in CASSANDRA-16956)
|
||||||
insert_driver_hooks()
|
insert_driver_hooks()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
|
|
@ -36,14 +36,6 @@ if [ -f "$CASSANDRA_CONF/cassandra-env.sh" ]; then
|
||||||
. "$CASSANDRA_CONF/cassandra-env.sh"
|
. "$CASSANDRA_CONF/cassandra-env.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Special-case path variables.
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN*|MINGW*)
|
|
||||||
CLASSPATH="`cygpath -p -w "$CLASSPATH"`"
|
|
||||||
CASSANDRA_CONF="`cygpath -p -w "$CASSANDRA_CONF"`"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
class="org.apache.cassandra.transport.Client"
|
class="org.apache.cassandra.transport.Client"
|
||||||
cassandra_parms="-Dlogback.configurationFile=logback-tools.xml"
|
cassandra_parms="-Dlogback.configurationFile=logback-tools.xml"
|
||||||
"$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" "$class" $@
|
"$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" "$class" $@
|
||||||
|
|
|
||||||
|
|
@ -1319,14 +1319,6 @@ enable_user_defined_functions: false
|
||||||
# This option has no effect, if enable_user_defined_functions is false.
|
# This option has no effect, if enable_user_defined_functions is false.
|
||||||
enable_scripted_user_defined_functions: false
|
enable_scripted_user_defined_functions: false
|
||||||
|
|
||||||
# The default Windows kernel timer and scheduling resolution is 15.6ms for power conservation.
|
|
||||||
# Lowering this value on Windows can provide much tighter latency and better throughput, however
|
|
||||||
# some virtualized environments may see a negative performance impact from changing this setting
|
|
||||||
# below their system default. The sysinternals 'clockres' tool can confirm your system's default
|
|
||||||
# setting.
|
|
||||||
windows_timer_interval: 1
|
|
||||||
|
|
||||||
|
|
||||||
# Enables encrypting data at-rest (on disk). Different key providers can be plugged in, but the default reads from
|
# Enables encrypting data at-rest (on disk). Different key providers can be plugged in, but the default reads from
|
||||||
# a JCE-style keystore. A single keystore can hold multiple keys, but the one referenced by
|
# a JCE-style keystore. A single keystore can hold multiple keys, but the one referenced by
|
||||||
# the "key_alias" is the only key that will be used for encrypt opertaions; previously used keys
|
# the "key_alias" is the only key that will be used for encrypt opertaions; previously used keys
|
||||||
|
|
|
||||||
|
|
@ -327,8 +327,8 @@ the first based on standard JMX security and the second which integrates
|
||||||
more closely with Cassandra's own auth subsystem.
|
more closely with Cassandra's own auth subsystem.
|
||||||
|
|
||||||
The default settings for Cassandra make JMX accessible only from
|
The default settings for Cassandra make JMX accessible only from
|
||||||
localhost. To enable remote JMX connections, edit `cassandra-env.sh` (or
|
localhost. To enable remote JMX connections, edit `cassandra-env.sh`
|
||||||
`cassandra-env.ps1` on Windows) to change the `LOCAL_JMX` setting to
|
to change the `LOCAL_JMX` setting to
|
||||||
`no`. Under the standard configuration, when remote JMX connections are
|
`no`. Under the standard configuration, when remote JMX connections are
|
||||||
enabled, `standard JMX authentication <standard-jmx-auth>` is also
|
enabled, `standard JMX authentication <standard-jmx-auth>` is also
|
||||||
switched on.
|
switched on.
|
||||||
|
|
@ -490,7 +490,7 @@ See also: xref:cql/security.adoc#permissions[`Permissions`].
|
||||||
|
|
||||||
JMX SSL configuration is controlled by a number of system properties,
|
JMX SSL configuration is controlled by a number of system properties,
|
||||||
some of which are optional. To turn on SSL, edit the relevant lines in
|
some of which are optional. To turn on SSL, edit the relevant lines in
|
||||||
`cassandra-env.sh` (or `cassandra-env.ps1` on Windows) to uncomment and
|
`cassandra-env.sh` to uncomment and
|
||||||
set the values of these properties as required:
|
set the values of these properties as required:
|
||||||
|
|
||||||
`com.sun.management.jmxremote.ssl`::
|
`com.sun.management.jmxremote.ssl`::
|
||||||
|
|
|
||||||
|
|
@ -884,7 +884,7 @@ class FilesReader(object):
|
||||||
self.max_rows = options.copy['maxrows']
|
self.max_rows = options.copy['maxrows']
|
||||||
self.skip_rows = options.copy['skiprows']
|
self.skip_rows = options.copy['skiprows']
|
||||||
self.fname = fname
|
self.fname = fname
|
||||||
self.sources = None # must be created later due to pickle problems on Windows
|
self.sources = None # might be initialised directly here? (see CASSANDRA-17350)
|
||||||
self.num_sources = 0
|
self.num_sources = 0
|
||||||
self.current_source = None
|
self.current_source = None
|
||||||
self.num_read = 0
|
self.num_read = 0
|
||||||
|
|
@ -1299,9 +1299,9 @@ class FeedingProcess(mp.Process):
|
||||||
self.inpipe = inpipe
|
self.inpipe = inpipe
|
||||||
self.outpipe = outpipe
|
self.outpipe = outpipe
|
||||||
self.worker_pipes = worker_pipes
|
self.worker_pipes = worker_pipes
|
||||||
self.inmsg = None # must be created after forking on Windows
|
self.inmsg = None # might be initialised directly here? (see CASSANDRA-17350)
|
||||||
self.outmsg = None # must be created after forking on Windows
|
self.outmsg = None # might be initialised directly here? (see CASSANDRA-17350)
|
||||||
self.worker_channels = None # must be created after forking on Windows
|
self.worker_channels = None # might be initialised directly here? (see CASSANDRA-17350)
|
||||||
self.reader = FilesReader(fname, options) if fname else PipeReader(inpipe, options)
|
self.reader = FilesReader(fname, options) if fname else PipeReader(inpipe, options)
|
||||||
self.send_meter = RateMeter(log_fcn=None, update_interval=1)
|
self.send_meter = RateMeter(log_fcn=None, update_interval=1)
|
||||||
self.ingest_rate = options.copy['ingestrate']
|
self.ingest_rate = options.copy['ingestrate']
|
||||||
|
|
@ -1405,8 +1405,8 @@ class ChildProcess(mp.Process):
|
||||||
super(ChildProcess, self).__init__(target=target)
|
super(ChildProcess, self).__init__(target=target)
|
||||||
self.inpipe = params['inpipe']
|
self.inpipe = params['inpipe']
|
||||||
self.outpipe = params['outpipe']
|
self.outpipe = params['outpipe']
|
||||||
self.inmsg = None # must be initialized after fork on Windows
|
self.inmsg = None # might be initialised directly here? (see CASSANDRA-17350)
|
||||||
self.outmsg = None # must be initialized after fork on Windows
|
self.outmsg = None # might be initialised directly here? (see CASSANDRA-17350)
|
||||||
self.ks = params['ks']
|
self.ks = params['ks']
|
||||||
self.table = params['table']
|
self.table = params['table']
|
||||||
self.local_dc = params['local_dc']
|
self.local_dc = params['local_dc']
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@ from . import wcwidth
|
||||||
from .displaying import colorme, get_str, FormattedValue, DEFAULT_VALUE_COLORS, NO_COLOR_MAP
|
from .displaying import colorme, get_str, FormattedValue, DEFAULT_VALUE_COLORS, NO_COLOR_MAP
|
||||||
from .util import UTC
|
from .util import UTC
|
||||||
|
|
||||||
is_win = platform.system() == 'Windows'
|
|
||||||
|
|
||||||
unicode_controlchars_re = re.compile(r'[\x00-\x31\x7f-\xa0]')
|
unicode_controlchars_re = re.compile(r'[\x00-\x31\x7f-\xa0]')
|
||||||
controlchars_re = re.compile(r'[\x00-\x31\x7f-\xff]')
|
controlchars_re = re.compile(r'[\x00-\x31\x7f-\xff]')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,8 @@ from . import basecase
|
||||||
from os.path import join, normpath
|
from os.path import join, normpath
|
||||||
|
|
||||||
|
|
||||||
def is_win():
|
import pty
|
||||||
return sys.platform in ("cygwin", "win32")
|
DEFAULT_PREFIX = os.linesep
|
||||||
|
|
||||||
if is_win():
|
|
||||||
from .winpty import WinPty
|
|
||||||
DEFAULT_PREFIX = ''
|
|
||||||
else:
|
|
||||||
import pty
|
|
||||||
DEFAULT_PREFIX = os.linesep
|
|
||||||
|
|
||||||
DEFAULT_CQLSH_PROMPT = DEFAULT_PREFIX + '(\S+@)?cqlsh(:\S+)?> '
|
DEFAULT_CQLSH_PROMPT = DEFAULT_PREFIX + '(\S+@)?cqlsh(:\S+)?> '
|
||||||
DEFAULT_CQLSH_TERM = 'xterm'
|
DEFAULT_CQLSH_TERM = 'xterm'
|
||||||
|
|
@ -56,13 +49,12 @@ def get_smm_sequence(term='xterm'):
|
||||||
before each prompt.
|
before each prompt.
|
||||||
"""
|
"""
|
||||||
result = ''
|
result = ''
|
||||||
if not is_win():
|
tput_proc = subprocess.Popen(['tput', '-T{}'.format(term), 'smm'], stdout=subprocess.PIPE)
|
||||||
tput_proc = subprocess.Popen(['tput', '-T{}'.format(term), 'smm'], stdout=subprocess.PIPE)
|
tput_stdout = tput_proc.communicate()[0]
|
||||||
tput_stdout = tput_proc.communicate()[0]
|
if (tput_stdout and (tput_stdout != b'')):
|
||||||
if (tput_stdout and (tput_stdout != b'')):
|
result = tput_stdout
|
||||||
result = tput_stdout
|
if isinstance(result, bytes):
|
||||||
if isinstance(result, bytes):
|
result = result.decode("utf-8")
|
||||||
result = result.decode("utf-8")
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
DEFAULT_SMM_SEQUENCE = get_smm_sequence()
|
DEFAULT_SMM_SEQUENCE = get_smm_sequence()
|
||||||
|
|
@ -97,7 +89,7 @@ class TimeoutError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def timing_out_itimer(seconds):
|
def timing_out(seconds):
|
||||||
if seconds is None:
|
if seconds is None:
|
||||||
yield
|
yield
|
||||||
return
|
return
|
||||||
|
|
@ -111,36 +103,6 @@ def timing_out_itimer(seconds):
|
||||||
finally:
|
finally:
|
||||||
signal.setitimer(signal.ITIMER_REAL, 0)
|
signal.setitimer(signal.ITIMER_REAL, 0)
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def timing_out_alarm(seconds):
|
|
||||||
if seconds is None:
|
|
||||||
yield
|
|
||||||
return
|
|
||||||
with raising_signal(signal.SIGALRM, TimeoutError):
|
|
||||||
oldval = signal.alarm(int(math.ceil(seconds)))
|
|
||||||
if oldval != 0:
|
|
||||||
signal.alarm(oldval)
|
|
||||||
raise RuntimeError("SIGALRM already in use")
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
signal.alarm(0)
|
|
||||||
|
|
||||||
if is_win():
|
|
||||||
try:
|
|
||||||
import eventlet
|
|
||||||
except ImportError as e:
|
|
||||||
sys.exit("evenlet library required to run cqlshlib tests on Windows")
|
|
||||||
|
|
||||||
def timing_out(seconds):
|
|
||||||
return eventlet.Timeout(seconds, TimeoutError)
|
|
||||||
else:
|
|
||||||
# setitimer is new in 2.6, but it's still worth supporting, for potentially
|
|
||||||
# faster tests because of sub-second resolution on timeouts.
|
|
||||||
if hasattr(signal, 'setitimer'):
|
|
||||||
timing_out = timing_out_itimer
|
|
||||||
else:
|
|
||||||
timing_out = timing_out_alarm
|
|
||||||
|
|
||||||
def noop(*a):
|
def noop(*a):
|
||||||
pass
|
pass
|
||||||
|
|
@ -149,8 +111,7 @@ class ProcRunner:
|
||||||
def __init__(self, path, tty=True, env=None, args=()):
|
def __init__(self, path, tty=True, env=None, args=()):
|
||||||
self.exe_path = path
|
self.exe_path = path
|
||||||
self.args = args
|
self.args = args
|
||||||
self.tty = bool(tty)
|
self.tty = tty
|
||||||
self.realtty = self.tty and not is_win()
|
|
||||||
if env is None:
|
if env is None:
|
||||||
env = {}
|
env = {}
|
||||||
self.env = env
|
self.env = env
|
||||||
|
|
@ -163,7 +124,7 @@ class ProcRunner:
|
||||||
stdin = stdout = stderr = None
|
stdin = stdout = stderr = None
|
||||||
cqlshlog.info("Spawning %r subprocess with args: %r and env: %r"
|
cqlshlog.info("Spawning %r subprocess with args: %r and env: %r"
|
||||||
% (self.exe_path, self.args, self.env))
|
% (self.exe_path, self.args, self.env))
|
||||||
if self.realtty:
|
if self.tty:
|
||||||
masterfd, slavefd = pty.openpty()
|
masterfd, slavefd = pty.openpty()
|
||||||
preexec = (lambda: set_controlling_pty(masterfd, slavefd))
|
preexec = (lambda: set_controlling_pty(masterfd, slavefd))
|
||||||
self.proc = subprocess.Popen((self.exe_path,) + tuple(self.args),
|
self.proc = subprocess.Popen((self.exe_path,) + tuple(self.args),
|
||||||
|
|
@ -181,15 +142,11 @@ class ProcRunner:
|
||||||
env=self.env, stdin=stdin, stdout=stdout,
|
env=self.env, stdin=stdin, stdout=stdout,
|
||||||
stderr=stderr, bufsize=0, close_fds=False)
|
stderr=stderr, bufsize=0, close_fds=False)
|
||||||
self.send = self.send_pipe
|
self.send = self.send_pipe
|
||||||
if self.tty:
|
self.read = self.read_pipe
|
||||||
self.winpty = WinPty(self.proc.stdout)
|
|
||||||
self.read = self.read_winpty
|
|
||||||
else:
|
|
||||||
self.read = self.read_pipe
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
cqlshlog.info("Closing %r subprocess." % (self.exe_path,))
|
cqlshlog.info("Closing %r subprocess." % (self.exe_path,))
|
||||||
if self.realtty:
|
if self.tty:
|
||||||
os.close(self.childpty)
|
os.close(self.childpty)
|
||||||
else:
|
else:
|
||||||
self.proc.stdin.close()
|
self.proc.stdin.close()
|
||||||
|
|
@ -216,12 +173,6 @@ class ProcRunner:
|
||||||
buf = buf.decode("utf-8")
|
buf = buf.decode("utf-8")
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def read_winpty(self, blksize, timeout=None):
|
|
||||||
buf = self.winpty.read(blksize, timeout)
|
|
||||||
if isinstance(buf, bytes):
|
|
||||||
buf = buf.decode("utf-8")
|
|
||||||
return buf
|
|
||||||
|
|
||||||
def read_until(self, until, blksize=4096, timeout=None,
|
def read_until(self, until, blksize=4096, timeout=None,
|
||||||
flags=0, ptty_timeout=None, replace=[]):
|
flags=0, ptty_timeout=None, replace=[]):
|
||||||
if not isinstance(until, Pattern):
|
if not isinstance(until, Pattern):
|
||||||
|
|
@ -273,8 +224,7 @@ class ProcRunner:
|
||||||
|
|
||||||
class CqlshRunner(ProcRunner):
|
class CqlshRunner(ProcRunner):
|
||||||
def __init__(self, path=None, host=None, port=None, keyspace=None, cqlver=None,
|
def __init__(self, path=None, host=None, port=None, keyspace=None, cqlver=None,
|
||||||
args=(), prompt=DEFAULT_CQLSH_PROMPT, env=None,
|
args=(), prompt=DEFAULT_CQLSH_PROMPT, env=None, tty=True, **kwargs):
|
||||||
win_force_colors=True, tty=True, **kwargs):
|
|
||||||
if path is None:
|
if path is None:
|
||||||
path = join(basecase.cqlsh_dir, 'cqlsh')
|
path = join(basecase.cqlsh_dir, 'cqlsh')
|
||||||
if host is None:
|
if host is None:
|
||||||
|
|
@ -283,9 +233,6 @@ class CqlshRunner(ProcRunner):
|
||||||
port = basecase.TEST_PORT
|
port = basecase.TEST_PORT
|
||||||
if env is None:
|
if env is None:
|
||||||
env = {}
|
env = {}
|
||||||
if is_win():
|
|
||||||
env['PYTHONUNBUFFERED'] = '1'
|
|
||||||
env.update(os.environ.copy())
|
|
||||||
env.setdefault('TERM', 'xterm')
|
env.setdefault('TERM', 'xterm')
|
||||||
env.setdefault('CQLSH_NO_BUNDLED', os.environ.get('CQLSH_NO_BUNDLED', ''))
|
env.setdefault('CQLSH_NO_BUNDLED', os.environ.get('CQLSH_NO_BUNDLED', ''))
|
||||||
env.setdefault('PYTHONPATH', os.environ.get('PYTHONPATH', ''))
|
env.setdefault('PYTHONPATH', os.environ.get('PYTHONPATH', ''))
|
||||||
|
|
@ -297,11 +244,6 @@ class CqlshRunner(ProcRunner):
|
||||||
args += ('--cqlversion', str(cqlver))
|
args += ('--cqlversion', str(cqlver))
|
||||||
if keyspace is not None:
|
if keyspace is not None:
|
||||||
args += ('--keyspace', keyspace.lower())
|
args += ('--keyspace', keyspace.lower())
|
||||||
if tty and is_win():
|
|
||||||
args += ('--tty',)
|
|
||||||
args += ('--encoding', 'utf-8')
|
|
||||||
if win_force_colors:
|
|
||||||
args += ('--color',)
|
|
||||||
if coverage:
|
if coverage:
|
||||||
args += ('--coverage',)
|
args += ('--coverage',)
|
||||||
self.keyspace = keyspace
|
self.keyspace = keyspace
|
||||||
|
|
@ -330,7 +272,7 @@ class CqlshRunner(ProcRunner):
|
||||||
output = output.replace(' \r', '')
|
output = output.replace(' \r', '')
|
||||||
output = output.replace('\r', '')
|
output = output.replace('\r', '')
|
||||||
output = output.replace(' \b', '')
|
output = output.replace(' \b', '')
|
||||||
if self.realtty:
|
if self.tty:
|
||||||
echo, output = output.split('\n', 1)
|
echo, output = output.split('\n', 1)
|
||||||
assert echo == cmd, "unexpected echo %r instead of %r" % (echo, cmd)
|
assert echo == cmd, "unexpected echo %r instead of %r" % (echo, cmd)
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,9 @@
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from .basecase import BaseTestCase, cqlsh, cqlshlog
|
from .basecase import BaseTestCase, cqlsh
|
||||||
from .cassconnect import create_db, remove_db, testrun_cqlsh
|
from .cassconnect import create_db, remove_db, testrun_cqlsh
|
||||||
from .run_cqlsh import TimeoutError
|
from .run_cqlsh import TimeoutError
|
||||||
import unittest
|
|
||||||
import sys
|
|
||||||
|
|
||||||
BEL = '\x07' # the terminal-bell character
|
BEL = '\x07' # the terminal-bell character
|
||||||
CTRL_C = '\x03'
|
CTRL_C = '\x03'
|
||||||
|
|
@ -39,8 +37,6 @@ COMPLETION_RESPONSE_TIME = 0.5
|
||||||
|
|
||||||
completion_separation_re = re.compile(r'\s+')
|
completion_separation_re = re.compile(r'\s+')
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform == "win32", 'Tab completion tests not supported on Windows')
|
|
||||||
class CqlshCompletionCase(BaseTestCase):
|
class CqlshCompletionCase(BaseTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ from __future__ import unicode_literals, with_statement
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import six
|
import six
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
@ -124,8 +122,7 @@ class TestCqlshOutput(BaseTestCase):
|
||||||
for termname in ('', 'dumb', 'vt100'):
|
for termname in ('', 'dumb', 'vt100'):
|
||||||
cqlshlog.debug('TERM=%r' % termname)
|
cqlshlog.debug('TERM=%r' % termname)
|
||||||
env['TERM'] = termname
|
env['TERM'] = termname
|
||||||
with testrun_cqlsh(tty=True, env=env,
|
with testrun_cqlsh(tty=True, env=env) as c:
|
||||||
win_force_colors=False) as c:
|
|
||||||
c.send('select * from has_all_types;\n')
|
c.send('select * from has_all_types;\n')
|
||||||
self.assertNoHasColors(c.read_to_next_prompt())
|
self.assertNoHasColors(c.read_to_next_prompt())
|
||||||
c.send('select count(*) from has_all_types;\n')
|
c.send('select count(*) from has_all_types;\n')
|
||||||
|
|
@ -588,7 +585,7 @@ class TestCqlshOutput(BaseTestCase):
|
||||||
outputlines = c.read_to_next_prompt().splitlines()
|
outputlines = c.read_to_next_prompt().splitlines()
|
||||||
|
|
||||||
start_index = 0
|
start_index = 0
|
||||||
if c.realtty:
|
if c.tty:
|
||||||
self.assertEqual(outputlines[start_index], 'use NONEXISTENTKEYSPACE;')
|
self.assertEqual(outputlines[start_index], 'use NONEXISTENTKEYSPACE;')
|
||||||
start_index = 1
|
start_index = 1
|
||||||
|
|
||||||
|
|
@ -781,7 +778,6 @@ class TestCqlshOutput(BaseTestCase):
|
||||||
self.assertRegex(output, '^Connected to .* at %s:%d$'
|
self.assertRegex(output, '^Connected to .* at %s:%d$'
|
||||||
% (re.escape(TEST_HOST), TEST_PORT))
|
% (re.escape(TEST_HOST), TEST_PORT))
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform == "win32", 'EOF signaling not supported on Windows')
|
|
||||||
def test_eof_prints_newline(self):
|
def test_eof_prints_newline(self):
|
||||||
with testrun_cqlsh(tty=True, env=self.default_env) as c:
|
with testrun_cqlsh(tty=True, env=self.default_env) as c:
|
||||||
c.send(CONTROL_D)
|
c.send(CONTROL_D)
|
||||||
|
|
@ -796,9 +792,8 @@ class TestCqlshOutput(BaseTestCase):
|
||||||
with testrun_cqlsh(tty=True, env=self.default_env) as c:
|
with testrun_cqlsh(tty=True, env=self.default_env) as c:
|
||||||
cmd = 'exit%s\n' % semicolon
|
cmd = 'exit%s\n' % semicolon
|
||||||
c.send(cmd)
|
c.send(cmd)
|
||||||
if c.realtty:
|
out = c.read_lines(1)[0].replace('\r', '')
|
||||||
out = c.read_lines(1)[0].replace('\r', '')
|
self.assertEqual(out, cmd)
|
||||||
self.assertEqual(out, cmd)
|
|
||||||
with self.assertRaises(BaseException) as cm:
|
with self.assertRaises(BaseException) as cm:
|
||||||
c.read_lines(1)
|
c.read_lines(1)
|
||||||
self.assertIn(type(cm.exception), (EOFError, OSError))
|
self.assertIn(type(cm.exception), (EOFError, OSError))
|
||||||
|
|
|
||||||
|
|
@ -392,8 +392,6 @@ public class Config
|
||||||
*/
|
*/
|
||||||
public volatile ConsistencyLevel ideal_consistency_level = null;
|
public volatile ConsistencyLevel ideal_consistency_level = null;
|
||||||
|
|
||||||
public int windows_timer_interval = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of the CQL prepared statements cache in MB.
|
* Size of the CQL prepared statements cache in MB.
|
||||||
* Defaults to 1/256th of the heap size or 10MB, whichever is greater.
|
* Defaults to 1/256th of the heap size or 10MB, whichever is greater.
|
||||||
|
|
|
||||||
|
|
@ -564,10 +564,6 @@ public class DatabaseDescriptor
|
||||||
|
|
||||||
if (conf.cdc_enabled)
|
if (conf.cdc_enabled)
|
||||||
{
|
{
|
||||||
// Windows memory-mapped CommitLog files is incompatible with CDC as we hard-link files in cdc_raw. Confirm we don't have both enabled.
|
|
||||||
if (FBUtilities.isWindows && conf.commitlog_compression == null)
|
|
||||||
throw new ConfigurationException("Cannot enable cdc on Windows with uncompressed commitlog.");
|
|
||||||
|
|
||||||
if (conf.cdc_raw_directory == null)
|
if (conf.cdc_raw_directory == null)
|
||||||
{
|
{
|
||||||
conf.cdc_raw_directory = storagedirFor("cdc_raw");
|
conf.cdc_raw_directory = storagedirFor("cdc_raw");
|
||||||
|
|
@ -2803,7 +2799,7 @@ public class DatabaseDescriptor
|
||||||
|
|
||||||
public static int getSSTablePreemptiveOpenIntervalInMB()
|
public static int getSSTablePreemptiveOpenIntervalInMB()
|
||||||
{
|
{
|
||||||
return FBUtilities.isWindows ? -1 : conf.sstable_preemptive_open_interval_in_mb;
|
return conf.sstable_preemptive_open_interval_in_mb;
|
||||||
}
|
}
|
||||||
public static void setSSTablePreemptiveOpenIntervalInMB(int mb)
|
public static void setSSTablePreemptiveOpenIntervalInMB(int mb)
|
||||||
{
|
{
|
||||||
|
|
@ -3046,11 +3042,6 @@ public class DatabaseDescriptor
|
||||||
return conf.tracetype_query_ttl;
|
return conf.tracetype_query_ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getWindowsTimerInterval()
|
|
||||||
{
|
|
||||||
return conf.windows_timer_interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getPreparedStatementsCacheSizeMB()
|
public static long getPreparedStatementsCacheSizeMB()
|
||||||
{
|
{
|
||||||
return preparedStatementsCacheSizeInMB;
|
return preparedStatementsCacheSizeInMB;
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ import org.apache.cassandra.schema.TableMetadata;
|
||||||
import org.apache.cassandra.service.snapshot.SnapshotManifest;
|
import org.apache.cassandra.service.snapshot.SnapshotManifest;
|
||||||
import org.apache.cassandra.service.snapshot.TableSnapshot;
|
import org.apache.cassandra.service.snapshot.TableSnapshot;
|
||||||
import org.apache.cassandra.utils.DirectorySizeCalculator;
|
import org.apache.cassandra.utils.DirectorySizeCalculator;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
import org.apache.cassandra.utils.JVMStabilityInspector;
|
import org.apache.cassandra.utils.JVMStabilityInspector;
|
||||||
import org.apache.cassandra.utils.Pair;
|
import org.apache.cassandra.utils.Pair;
|
||||||
|
|
||||||
|
|
@ -1112,10 +1111,7 @@ public class Directories
|
||||||
}
|
}
|
||||||
catch (FSWriteError e)
|
catch (FSWriteError e)
|
||||||
{
|
{
|
||||||
if (FBUtilities.isWindows)
|
throw e;
|
||||||
SnapshotDeletingTask.addFailedSnapshot(snapshotDir);
|
|
||||||
else
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.cassandra.db;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import org.apache.cassandra.io.util.File;
|
|
||||||
import org.apache.cassandra.io.util.FileOutputStreamPlus;
|
|
||||||
import org.apache.cassandra.io.util.FileReader;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
|
||||||
import org.apache.cassandra.io.util.FileUtils;
|
|
||||||
|
|
||||||
import static org.apache.cassandra.io.util.File.WriteMode.APPEND;
|
|
||||||
|
|
||||||
|
|
||||||
public class WindowsFailedSnapshotTracker
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(WindowsFailedSnapshotTracker.class);
|
|
||||||
private static PrintWriter _failedSnapshotFile;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
// Need to handle null for unit tests
|
|
||||||
public static final String TODELETEFILE = System.getenv("CASSANDRA_HOME") == null
|
|
||||||
? ".toDelete"
|
|
||||||
: System.getenv("CASSANDRA_HOME") + File.pathSeparator() + ".toDelete";
|
|
||||||
|
|
||||||
public static void deleteOldSnapshots()
|
|
||||||
{
|
|
||||||
if (new File(TODELETEFILE).exists())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(TODELETEFILE)))
|
|
||||||
{
|
|
||||||
String snapshotDirectory;
|
|
||||||
while ((snapshotDirectory = reader.readLine()) != null)
|
|
||||||
{
|
|
||||||
File f = new File(snapshotDirectory);
|
|
||||||
|
|
||||||
// Skip folders that aren't a subset of temp or a data folder. We don't want people to accidentally
|
|
||||||
// delete something important by virtue of adding something invalid to the .toDelete file.
|
|
||||||
boolean validFolder = FileUtils.isSubDirectory(new File(System.getenv("TEMP")), f);
|
|
||||||
for (String s : DatabaseDescriptor.getAllDataFileLocations())
|
|
||||||
validFolder |= FileUtils.isSubDirectory(new File(s), f);
|
|
||||||
|
|
||||||
if (!validFolder)
|
|
||||||
{
|
|
||||||
logger.warn("Skipping invalid directory found in .toDelete: {}. Only %TEMP% or data file subdirectories are valid.", f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Could be a non-existent directory if deletion worked on previous JVM shutdown.
|
|
||||||
if (f.exists())
|
|
||||||
{
|
|
||||||
logger.warn("Discovered obsolete snapshot. Deleting directory [{}]", snapshotDirectory);
|
|
||||||
FileUtils.deleteRecursive(new File(snapshotDirectory));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only delete the old .toDelete file if we succeed in deleting all our known bad snapshots.
|
|
||||||
new File(TODELETEFILE).delete();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
logger.warn("Failed to open {}. Obsolete snapshots from previous runs will not be deleted.", TODELETEFILE, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_failedSnapshotFile = new PrintWriter(new OutputStreamWriter(new FileOutputStreamPlus(TODELETEFILE, APPEND)));
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(String.format("Failed to create failed snapshot tracking file [%s]. Aborting", TODELETEFILE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized void handleFailedSnapshot(File dir)
|
|
||||||
{
|
|
||||||
assert _failedSnapshotFile != null : "_failedSnapshotFile not initialized within WindowsFailedSnapshotTracker";
|
|
||||||
FileUtils.deleteRecursiveOnExit(dir);
|
|
||||||
_failedSnapshotFile.println(dir.toString());
|
|
||||||
_failedSnapshotFile.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public static void resetForTests()
|
|
||||||
{
|
|
||||||
_failedSnapshotFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -351,7 +351,6 @@ public class CommitLogSegmentManagerCDC extends AbstractCommitLogSegmentManager
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
resetSize();
|
resetSize();
|
||||||
// The Arrays.stream approach is considerably slower on Windows than linux
|
|
||||||
Files.walkFileTree(path.toPath(), this);
|
Files.walkFileTree(path.toPath(), this);
|
||||||
sizeInProgress.getAndSet(getAllocatedSize());
|
sizeInProgress.getAndSet(getAllocatedSize());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ import org.apache.cassandra.io.sstable.Descriptor;
|
||||||
import org.apache.cassandra.io.sstable.ISSTableScanner;
|
import org.apache.cassandra.io.sstable.ISSTableScanner;
|
||||||
import org.apache.cassandra.io.sstable.IndexSummaryRedistribution;
|
import org.apache.cassandra.io.sstable.IndexSummaryRedistribution;
|
||||||
import org.apache.cassandra.io.sstable.SSTableRewriter;
|
import org.apache.cassandra.io.sstable.SSTableRewriter;
|
||||||
import org.apache.cassandra.io.sstable.SnapshotDeletingTask;
|
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
||||||
import org.apache.cassandra.io.sstable.metadata.MetadataCollector;
|
import org.apache.cassandra.io.sstable.metadata.MetadataCollector;
|
||||||
|
|
@ -1846,7 +1845,6 @@ public class CompactionManager implements CompactionManagerMBean
|
||||||
static class CompactionExecutor extends WrappedExecutorPlus
|
static class CompactionExecutor extends WrappedExecutorPlus
|
||||||
{
|
{
|
||||||
static final ThreadGroup compactionThreadGroup = executorFactory().newThreadGroup("compaction");
|
static final ThreadGroup compactionThreadGroup = executorFactory().newThreadGroup("compaction");
|
||||||
private static final WithResources RESCHEDULE_FAILED = () -> SnapshotDeletingTask::rescheduleFailedTasks;
|
|
||||||
|
|
||||||
public CompactionExecutor()
|
public CompactionExecutor()
|
||||||
{
|
{
|
||||||
|
|
@ -1901,12 +1899,12 @@ public class CompactionManager implements CompactionManagerMBean
|
||||||
|
|
||||||
public void execute(Runnable command)
|
public void execute(Runnable command)
|
||||||
{
|
{
|
||||||
executor.execute(RESCHEDULE_FAILED, command);
|
executor.execute(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> submit(Callable<T> task)
|
public <T> Future<T> submit(Callable<T> task)
|
||||||
{
|
{
|
||||||
return executor.submit(RESCHEDULE_FAILED, task);
|
return executor.submit(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Future<T> submit(Runnable task, T result)
|
public <T> Future<T> submit(Runnable task, T result)
|
||||||
|
|
|
||||||
|
|
@ -171,9 +171,6 @@ public class CompactionTask extends AbstractCompactionTask
|
||||||
long[] mergedRowCounts;
|
long[] mergedRowCounts;
|
||||||
long totalSourceCQLRows;
|
long totalSourceCQLRows;
|
||||||
|
|
||||||
// SSTableScanners need to be closed before markCompactedSSTablesReplaced call as scanners contain references
|
|
||||||
// to both ifile and dfile and SSTR will throw deletion errors on Windows if it tries to delete before scanner is closed.
|
|
||||||
// See CASSANDRA-8019 and CASSANDRA-8399
|
|
||||||
int nowInSec = FBUtilities.nowInSeconds();
|
int nowInSec = FBUtilities.nowInSeconds();
|
||||||
try (Refs<SSTableReader> refs = Refs.ref(actuallyCompact);
|
try (Refs<SSTableReader> refs = Refs.ref(actuallyCompact);
|
||||||
AbstractCompactionStrategy.ScannerList scanners = strategy.getScanners(actuallyCompact);
|
AbstractCompactionStrategy.ScannerList scanners = strategy.getScanners(actuallyCompact);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.apache.cassandra.io.FSError;
|
import org.apache.cassandra.io.FSError;
|
||||||
import org.apache.cassandra.io.FSReadError;
|
import org.apache.cassandra.io.FSReadError;
|
||||||
import org.apache.cassandra.io.util.FileUtils;
|
import org.apache.cassandra.io.util.FileUtils;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
import org.apache.cassandra.utils.NativeLibrary;
|
import org.apache.cassandra.utils.NativeLibrary;
|
||||||
|
|
||||||
import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_MISSING_NATIVE_FILE_HINTS;
|
import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_MISSING_NATIVE_FILE_HINTS;
|
||||||
|
|
@ -49,7 +48,7 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_MIS
|
||||||
final class LogReplica implements AutoCloseable
|
final class LogReplica implements AutoCloseable
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LogReplica.class);
|
private static final Logger logger = LoggerFactory.getLogger(LogReplica.class);
|
||||||
private static final boolean REQUIRE_FD = !FBUtilities.isWindows && !IGNORE_MISSING_NATIVE_FILE_HINTS.getBoolean();
|
private static final boolean REQUIRE_FD = !IGNORE_MISSING_NATIVE_FILE_HINTS.getBoolean();
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private int directoryDescriptor;
|
private int directoryDescriptor;
|
||||||
|
|
@ -67,7 +66,7 @@ final class LogReplica implements AutoCloseable
|
||||||
static LogReplica open(File file)
|
static LogReplica open(File file)
|
||||||
{
|
{
|
||||||
int folderFD = NativeLibrary.tryOpenDirectory(file.parent().path());
|
int folderFD = NativeLibrary.tryOpenDirectory(file.parent().path());
|
||||||
if (folderFD == -1 && !FBUtilities.isWindows)
|
if (folderFD == -1)
|
||||||
throw new FSReadError(new IOException(String.format("Invalid folder descriptor trying to create log replica %s", file.parent().path())), file.parent().path());
|
throw new FSReadError(new IOException(String.format("Invalid folder descriptor trying to create log replica %s", file.parent().path())), file.parent().path());
|
||||||
|
|
||||||
return new LogReplica(file, folderFD);
|
return new LogReplica(file, folderFD);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ import org.apache.cassandra.io.FSWriteError;
|
||||||
import org.apache.cassandra.io.sstable.Component;
|
import org.apache.cassandra.io.sstable.Component;
|
||||||
import org.apache.cassandra.io.sstable.Descriptor;
|
import org.apache.cassandra.io.sstable.Descriptor;
|
||||||
import org.apache.cassandra.io.sstable.SSTable;
|
import org.apache.cassandra.io.sstable.SSTable;
|
||||||
import org.apache.cassandra.io.sstable.SnapshotDeletingTask;
|
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
||||||
import org.apache.cassandra.io.util.File;
|
import org.apache.cassandra.io.util.File;
|
||||||
import org.apache.cassandra.io.util.FileUtils;
|
import org.apache.cassandra.io.util.FileUtils;
|
||||||
|
|
@ -114,8 +113,7 @@ class LogTransaction extends Transactional.AbstractTransactional implements Tran
|
||||||
// We need an explicit lock because the transaction tidier cannot store a reference to the transaction
|
// We need an explicit lock because the transaction tidier cannot store a reference to the transaction
|
||||||
private final Object lock;
|
private final Object lock;
|
||||||
private final Ref<LogTransaction> selfRef;
|
private final Ref<LogTransaction> selfRef;
|
||||||
// Deleting sstables is tricky because the mmapping might not have been finalized yet,
|
// Deleting sstables is tricky because the mmapping might not have been finalized yet.
|
||||||
// and delete will fail (on Windows) until it is (we only force the unmapping on SUN VMs).
|
|
||||||
// Additionally, we need to make sure to delete the data file first, so on restart the others
|
// Additionally, we need to make sure to delete the data file first, so on restart the others
|
||||||
// will be recognized as GCable.
|
// will be recognized as GCable.
|
||||||
private static final Queue<Runnable> failedDeletions = new ConcurrentLinkedQueue<>();
|
private static final Queue<Runnable> failedDeletions = new ConcurrentLinkedQueue<>();
|
||||||
|
|
@ -433,9 +431,6 @@ class LogTransaction extends Transactional.AbstractTransactional implements Tran
|
||||||
Runnable task;
|
Runnable task;
|
||||||
while ( null != (task = failedDeletions.poll()))
|
while ( null != (task = failedDeletions.poll()))
|
||||||
ScheduledExecutors.nonPeriodicTasks.submit(task);
|
ScheduledExecutors.nonPeriodicTasks.submit(task);
|
||||||
|
|
||||||
// On Windows, snapshots cannot be deleted so long as a segment of the root element is memory-mapped in NTFS.
|
|
||||||
SnapshotDeletingTask.rescheduleFailedTasks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void waitForDeletions()
|
static void waitForDeletions()
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,7 @@ public class CassandraOutgoingFile implements OutgoingStream
|
||||||
{
|
{
|
||||||
// Acquire lock to avoid concurrent sstable component mutation because of stats update or index summary
|
// Acquire lock to avoid concurrent sstable component mutation because of stats update or index summary
|
||||||
// redistribution, otherwise file sizes recorded in component manifest will be different from actual
|
// redistribution, otherwise file sizes recorded in component manifest will be different from actual
|
||||||
// file sizes. (Note: Windows doesn't support atomic replace and index summary redistribution deletes
|
// file sizes.
|
||||||
// existing file first)
|
|
||||||
// Recreate the latest manifest and hard links for mutatable components in case they are modified.
|
// Recreate the latest manifest and hard links for mutatable components in case they are modified.
|
||||||
try (ComponentContext context = sstable.runWithLock(ignored -> ComponentContext.create(sstable.descriptor)))
|
try (ComponentContext context = sstable.runWithLock(ignored -> ComponentContext.create(sstable.descriptor)))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import org.apache.cassandra.io.FSError;
|
||||||
import org.apache.cassandra.io.FSReadError;
|
import org.apache.cassandra.io.FSReadError;
|
||||||
import org.apache.cassandra.io.FSWriteError;
|
import org.apache.cassandra.io.FSWriteError;
|
||||||
import org.apache.cassandra.io.util.FileUtils;
|
import org.apache.cassandra.io.util.FileUtils;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
import org.apache.cassandra.utils.NativeLibrary;
|
import org.apache.cassandra.utils.NativeLibrary;
|
||||||
import org.apache.cassandra.utils.SyncUtil;
|
import org.apache.cassandra.utils.SyncUtil;
|
||||||
|
|
||||||
|
|
@ -162,7 +161,7 @@ final class HintsCatalog
|
||||||
FileUtils.handleFSErrorAndPropagate(e);
|
FileUtils.handleFSErrorAndPropagate(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!FBUtilities.isWindows)
|
else
|
||||||
{
|
{
|
||||||
logger.error("Unable to open directory {}", hintsDirectory.absolutePath());
|
logger.error("Unable to open directory {}", hintsDirectory.absolutePath());
|
||||||
FileUtils.handleFSErrorAndPropagate(new FSWriteError(new IOException(String.format("Unable to open hint directory %s", hintsDirectory.absolutePath())), hintsDirectory.absolutePath()));
|
FileUtils.handleFSErrorAndPropagate(new FSWriteError(new IOException(String.format("Unable to open hint directory %s", hintsDirectory.absolutePath())), hintsDirectory.absolutePath()));
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.cassandra.io.sstable;
|
|
||||||
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import org.apache.cassandra.io.util.File;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import org.apache.cassandra.concurrent.ScheduledExecutors;
|
|
||||||
import org.apache.cassandra.db.WindowsFailedSnapshotTracker;
|
|
||||||
import org.apache.cassandra.io.FSWriteError;
|
|
||||||
import org.apache.cassandra.io.util.FileUtils;
|
|
||||||
|
|
||||||
public class SnapshotDeletingTask implements Runnable
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SnapshotDeletingTask.class);
|
|
||||||
|
|
||||||
public final File path;
|
|
||||||
private static final Queue<Runnable> failedTasks = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
public static void addFailedSnapshot(File path)
|
|
||||||
{
|
|
||||||
logger.warn("Failed to delete snapshot [{}]. Will retry after further sstable deletions. Folder will be deleted on JVM shutdown or next node restart on crash.", path);
|
|
||||||
WindowsFailedSnapshotTracker.handleFailedSnapshot(path);
|
|
||||||
failedTasks.add(new SnapshotDeletingTask(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SnapshotDeletingTask(File path)
|
|
||||||
{
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
FileUtils.deleteRecursive(path);
|
|
||||||
logger.info("Successfully deleted snapshot {}.", path);
|
|
||||||
}
|
|
||||||
catch (FSWriteError e)
|
|
||||||
{
|
|
||||||
failedTasks.add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retry all failed deletions.
|
|
||||||
*/
|
|
||||||
public static void rescheduleFailedTasks()
|
|
||||||
{
|
|
||||||
Runnable task;
|
|
||||||
while ( null != (task = failedTasks.poll()))
|
|
||||||
ScheduledExecutors.nonPeriodicTasks.submit(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public static int pendingDeletionCount()
|
|
||||||
{
|
|
||||||
return failedTasks.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -36,7 +36,6 @@ import org.apache.cassandra.io.sstable.Component;
|
||||||
import org.apache.cassandra.io.sstable.CorruptSSTableException;
|
import org.apache.cassandra.io.sstable.CorruptSSTableException;
|
||||||
import org.apache.cassandra.io.sstable.Descriptor;
|
import org.apache.cassandra.io.sstable.Descriptor;
|
||||||
import org.apache.cassandra.io.sstable.format.Version;
|
import org.apache.cassandra.io.sstable.format.Version;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
|
|
||||||
import static org.apache.cassandra.utils.FBUtilities.updateChecksumInt;
|
import static org.apache.cassandra.utils.FBUtilities.updateChecksumInt;
|
||||||
|
|
||||||
|
|
@ -268,10 +267,6 @@ public class MetadataSerializer implements IMetadataSerializer
|
||||||
Throwables.throwIfInstanceOf(e, FileNotFoundException.class);
|
Throwables.throwIfInstanceOf(e, FileNotFoundException.class);
|
||||||
throw new FSWriteError(e, filePath);
|
throw new FSWriteError(e, filePath);
|
||||||
}
|
}
|
||||||
// we cant move a file on top of another file in windows:
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
FileUtils.delete(descriptor.filenameFor(Component.STATS));
|
|
||||||
FileUtils.renameWithConfirm(filePath, descriptor.filenameFor(Component.STATS));
|
FileUtils.renameWithConfirm(filePath, descriptor.filenameFor(Component.STATS));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -352,8 +352,6 @@ public final class PathUtils
|
||||||
public static boolean tryRename(Path from, Path to)
|
public static boolean tryRename(Path from, Path to)
|
||||||
{
|
{
|
||||||
logger.trace("Renaming {} to {}", from, to);
|
logger.trace("Renaming {} to {}", from, to);
|
||||||
// this is not FSWE because usually when we see it it's because we didn't close the file before renaming it,
|
|
||||||
// and Windows is picky about that.
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
atomicMoveWithFallback(from, to);
|
atomicMoveWithFallback(from, to);
|
||||||
|
|
@ -369,8 +367,6 @@ public final class PathUtils
|
||||||
public static void rename(Path from, Path to)
|
public static void rename(Path from, Path to)
|
||||||
{
|
{
|
||||||
logger.trace("Renaming {} to {}", from, to);
|
logger.trace("Renaming {} to {}", from, to);
|
||||||
// this is not FSWE because usually when we see it it's because we didn't close the file before renaming it,
|
|
||||||
// and Windows is picky about that.
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
atomicMoveWithFallback(from, to);
|
atomicMoveWithFallback(from, to);
|
||||||
|
|
|
||||||
|
|
@ -177,9 +177,7 @@ public class InboundConnectionInitiator
|
||||||
throw new ConfigurationException(bind + " is in use by another process. Change listen_address:storage_port " +
|
throw new ConfigurationException(bind + " is in use by another process. Change listen_address:storage_port " +
|
||||||
"in cassandra.yaml to values that do not conflict with other services");
|
"in cassandra.yaml to values that do not conflict with other services");
|
||||||
}
|
}
|
||||||
// looking at the jdk source, solaris/windows bind failue messages both use the phrase "cannot assign requested address".
|
else if (causeString.contains("cannot assign requested address"))
|
||||||
// windows message uses "Cannot" (with a capital 'C'), and solaris (a/k/a *nux) doe not. hence we search for "annot" <sigh>
|
|
||||||
else if (causeString.contains("annot assign requested address"))
|
|
||||||
{
|
{
|
||||||
throw new ConfigurationException("Unable to bind to address " + bind
|
throw new ConfigurationException("Unable to bind to address " + bind
|
||||||
+ ". Set listen_address in cassandra.yaml to an interface you can bind to, e.g., your private IP address on EC2");
|
+ ". Set listen_address in cassandra.yaml to an interface you can bind to, e.g., your private IP address on EC2");
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,12 @@ import com.google.common.base.Joiner;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.apache.cassandra.config.Config;
|
|
||||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||||
import org.apache.cassandra.dht.IPartitioner;
|
import org.apache.cassandra.dht.IPartitioner;
|
||||||
import org.apache.cassandra.dht.Range;
|
import org.apache.cassandra.dht.Range;
|
||||||
import org.apache.cassandra.dht.Token;
|
import org.apache.cassandra.dht.Token;
|
||||||
import org.apache.cassandra.streaming.PreviewKind;
|
import org.apache.cassandra.streaming.PreviewKind;
|
||||||
import org.apache.cassandra.repair.RepairParallelism;
|
import org.apache.cassandra.repair.RepairParallelism;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repair options.
|
* Repair options.
|
||||||
|
|
@ -285,16 +283,8 @@ public class RepairOption
|
||||||
|
|
||||||
public RepairOption(RepairParallelism parallelism, boolean primaryRange, boolean incremental, boolean trace, int jobThreads, Collection<Range<Token>> ranges, boolean isSubrangeRepair, boolean pullRepair, boolean forceRepair, PreviewKind previewKind, boolean optimiseStreams, boolean ignoreUnreplicatedKeyspaces)
|
public RepairOption(RepairParallelism parallelism, boolean primaryRange, boolean incremental, boolean trace, int jobThreads, Collection<Range<Token>> ranges, boolean isSubrangeRepair, boolean pullRepair, boolean forceRepair, PreviewKind previewKind, boolean optimiseStreams, boolean ignoreUnreplicatedKeyspaces)
|
||||||
{
|
{
|
||||||
if (FBUtilities.isWindows &&
|
|
||||||
(DatabaseDescriptor.getDiskAccessMode() != Config.DiskAccessMode.standard || DatabaseDescriptor.getIndexAccessMode() != Config.DiskAccessMode.standard) &&
|
|
||||||
parallelism == RepairParallelism.SEQUENTIAL)
|
|
||||||
{
|
|
||||||
logger.warn("Sequential repair disabled when memory-mapped I/O is configured on Windows. Reverting to parallel.");
|
|
||||||
this.parallelism = RepairParallelism.PARALLEL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this.parallelism = parallelism;
|
|
||||||
|
|
||||||
|
this.parallelism = parallelism;
|
||||||
this.primaryRange = primaryRange;
|
this.primaryRange = primaryRange;
|
||||||
this.incremental = incremental;
|
this.incremental = incremental;
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,10 @@ public final class SchemaConstants
|
||||||
public static final Set<String> REPLICATED_SYSTEM_KEYSPACE_NAMES =
|
public static final Set<String> REPLICATED_SYSTEM_KEYSPACE_NAMES =
|
||||||
ImmutableSet.of(TRACE_KEYSPACE_NAME, AUTH_KEYSPACE_NAME, DISTRIBUTED_KEYSPACE_NAME);
|
ImmutableSet.of(TRACE_KEYSPACE_NAME, AUTH_KEYSPACE_NAME, DISTRIBUTED_KEYSPACE_NAME);
|
||||||
/**
|
/**
|
||||||
* longest permissible KS or CF name. Our main concern is that filename not be more than 255 characters;
|
* The longest permissible KS or CF name.
|
||||||
* the filename will contain both the KS and CF names. Since non-schema-name components only take up
|
*
|
||||||
* ~64 characters, we could allow longer names than this, but on Windows, the entire path should be not greater than
|
* Before CASSANDRA-16956, we used to care about not having the entire path longer than 255 characters because of
|
||||||
* 255 characters, so a lower limit here helps avoid problems. See CASSANDRA-4110.
|
* Windows support but this limit is by implementing CASSANDRA-16956 not in effect anymore.
|
||||||
*/
|
*/
|
||||||
public static final int NAME_LENGTH = 48;
|
public static final int NAME_LENGTH = 48;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ import org.apache.cassandra.db.Keyspace;
|
||||||
import org.apache.cassandra.db.SizeEstimatesRecorder;
|
import org.apache.cassandra.db.SizeEstimatesRecorder;
|
||||||
import org.apache.cassandra.db.SystemKeyspace;
|
import org.apache.cassandra.db.SystemKeyspace;
|
||||||
import org.apache.cassandra.db.SystemKeyspaceMigrator40;
|
import org.apache.cassandra.db.SystemKeyspaceMigrator40;
|
||||||
import org.apache.cassandra.db.WindowsFailedSnapshotTracker;
|
|
||||||
import org.apache.cassandra.db.commitlog.CommitLog;
|
import org.apache.cassandra.db.commitlog.CommitLog;
|
||||||
import org.apache.cassandra.db.virtual.SystemViewsKeyspace;
|
import org.apache.cassandra.db.virtual.SystemViewsKeyspace;
|
||||||
import org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry;
|
import org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry;
|
||||||
|
|
@ -84,7 +83,6 @@ import org.apache.cassandra.utils.JVMStabilityInspector;
|
||||||
import org.apache.cassandra.utils.MBeanWrapper;
|
import org.apache.cassandra.utils.MBeanWrapper;
|
||||||
import org.apache.cassandra.utils.Mx4jTool;
|
import org.apache.cassandra.utils.Mx4jTool;
|
||||||
import org.apache.cassandra.utils.NativeLibrary;
|
import org.apache.cassandra.utils.NativeLibrary;
|
||||||
import org.apache.cassandra.utils.WindowsTimer;
|
|
||||||
import org.apache.cassandra.utils.concurrent.Future;
|
import org.apache.cassandra.utils.concurrent.Future;
|
||||||
import org.apache.cassandra.utils.concurrent.FutureCombiner;
|
import org.apache.cassandra.utils.concurrent.FutureCombiner;
|
||||||
|
|
||||||
|
|
@ -241,10 +239,6 @@ public class CassandraDaemon
|
||||||
exitOrFail(StartupException.ERR_WRONG_DISK_STATE, e.getMessage(), e);
|
exitOrFail(StartupException.ERR_WRONG_DISK_STATE, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete any failed snapshot deletions on Windows - see CASSANDRA-9658
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
WindowsFailedSnapshotTracker.deleteOldSnapshots();
|
|
||||||
|
|
||||||
maybeInitJmx();
|
maybeInitJmx();
|
||||||
|
|
||||||
Mx4jTool.maybeLoad();
|
Mx4jTool.maybeLoad();
|
||||||
|
|
@ -699,11 +693,6 @@ public class CassandraDaemon
|
||||||
destroyClientTransports();
|
destroyClientTransports();
|
||||||
StorageService.instance.setRpcReady(false);
|
StorageService.instance.setRpcReady(false);
|
||||||
|
|
||||||
// On windows, we need to stop the entire system as prunsrv doesn't have the jsvc hooks
|
|
||||||
// We rely on the shutdown hook to drain the node
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
System.exit(0);
|
|
||||||
|
|
||||||
if (jmxServer != null)
|
if (jmxServer != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -744,13 +733,6 @@ public class CassandraDaemon
|
||||||
|
|
||||||
registerNativeAccess();
|
registerNativeAccess();
|
||||||
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
{
|
|
||||||
// We need to adjust the system timer on windows from the default 15ms down to the minimum of 1ms as this
|
|
||||||
// impacts timer intervals, thread scheduling, driver interrupts, etc.
|
|
||||||
WindowsTimer.startTimerPeriod(DatabaseDescriptor.getWindowsTimerInterval());
|
|
||||||
}
|
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
String pidFile = CASSANDRA_PID_FILE.getString();
|
String pidFile = CASSANDRA_PID_FILE.getString();
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,6 @@ public class StartupChecks
|
||||||
{
|
{
|
||||||
public void execute()
|
public void execute()
|
||||||
{
|
{
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
return;
|
|
||||||
String jemalloc = System.getProperty("cassandra.libjemalloc");
|
String jemalloc = System.getProperty("cassandra.libjemalloc");
|
||||||
if (jemalloc == null)
|
if (jemalloc == null)
|
||||||
logger.warn("jemalloc shared library could not be preloaded to speed up memory allocations");
|
logger.warn("jemalloc shared library could not be preloaded to speed up memory allocations");
|
||||||
|
|
|
||||||
|
|
@ -784,10 +784,6 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
||||||
public void runMayThrow() throws InterruptedException, ExecutionException, IOException
|
public void runMayThrow() throws InterruptedException, ExecutionException, IOException
|
||||||
{
|
{
|
||||||
drain(true);
|
drain(true);
|
||||||
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
WindowsTimer.endTimerPeriod(DatabaseDescriptor.getWindowsTimerInterval());
|
|
||||||
|
|
||||||
LoggingSupportFactory.getLoggingSupport().onShutdown();
|
LoggingSupportFactory.getLoggingSupport().onShutdown();
|
||||||
}
|
}
|
||||||
}, "StorageServiceShutdownHook");
|
}, "StorageServiceShutdownHook");
|
||||||
|
|
@ -892,9 +888,6 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
|
||||||
|
|
||||||
if (drainOnShutdown != null)
|
if (drainOnShutdown != null)
|
||||||
Runtime.getRuntime().removeShutdownHook(drainOnShutdown);
|
Runtime.getRuntime().removeShutdownHook(drainOnShutdown);
|
||||||
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
WindowsTimer.endTimerPeriod(DatabaseDescriptor.getWindowsTimerInterval());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldBootstrap()
|
private boolean shouldBootstrap()
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,6 @@ public class SSTableExport
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
// throwing exception outside main with broken pipe causes windows cmd to hang
|
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,6 @@ public class FBUtilities
|
||||||
private static final String DEFAULT_TRIGGER_DIR = "triggers";
|
private static final String DEFAULT_TRIGGER_DIR = "triggers";
|
||||||
|
|
||||||
private static final String OPERATING_SYSTEM = System.getProperty("os.name").toLowerCase();
|
private static final String OPERATING_SYSTEM = System.getProperty("os.name").toLowerCase();
|
||||||
public static final boolean isWindows = OPERATING_SYSTEM.contains("windows");
|
|
||||||
public static final boolean isLinux = OPERATING_SYSTEM.contains("linux");
|
public static final boolean isLinux = OPERATING_SYSTEM.contains("linux");
|
||||||
|
|
||||||
private static volatile InetAddress localInetAddress;
|
private static volatile InetAddress localInetAddress;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ import static org.apache.cassandra.config.CassandraRelevantProperties.OS_ARCH;
|
||||||
import static org.apache.cassandra.config.CassandraRelevantProperties.OS_NAME;
|
import static org.apache.cassandra.config.CassandraRelevantProperties.OS_NAME;
|
||||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.LINUX;
|
import static org.apache.cassandra.utils.NativeLibrary.OSType.LINUX;
|
||||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.MAC;
|
import static org.apache.cassandra.utils.NativeLibrary.OSType.MAC;
|
||||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.WINDOWS;
|
|
||||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.AIX;
|
import static org.apache.cassandra.utils.NativeLibrary.OSType.AIX;
|
||||||
|
|
||||||
public final class NativeLibrary
|
public final class NativeLibrary
|
||||||
|
|
@ -50,7 +49,6 @@ public final class NativeLibrary
|
||||||
{
|
{
|
||||||
LINUX,
|
LINUX,
|
||||||
MAC,
|
MAC,
|
||||||
WINDOWS,
|
|
||||||
AIX,
|
AIX,
|
||||||
OTHER;
|
OTHER;
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +97,6 @@ public final class NativeLibrary
|
||||||
switch (osType)
|
switch (osType)
|
||||||
{
|
{
|
||||||
case MAC: wrappedLibrary = new NativeLibraryDarwin(); break;
|
case MAC: wrappedLibrary = new NativeLibraryDarwin(); break;
|
||||||
case WINDOWS: wrappedLibrary = new NativeLibraryWindows(); break;
|
|
||||||
case LINUX:
|
case LINUX:
|
||||||
case AIX:
|
case AIX:
|
||||||
case OTHER:
|
case OTHER:
|
||||||
|
|
@ -143,10 +140,8 @@ public final class NativeLibrary
|
||||||
return LINUX;
|
return LINUX;
|
||||||
else if (osName.contains("mac"))
|
else if (osName.contains("mac"))
|
||||||
return MAC;
|
return MAC;
|
||||||
else if (osName.contains("windows"))
|
|
||||||
return WINDOWS;
|
|
||||||
|
|
||||||
logger.warn("the current operating system, {}, is unsupported by cassandra", osName);
|
logger.warn("the current operating system, {}, is unsupported by Cassandra", osName);
|
||||||
if (osName.contains("aix"))
|
if (osName.contains("aix"))
|
||||||
return AIX;
|
return AIX;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.cassandra.utils;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.sun.jna.LastErrorException;
|
|
||||||
import com.sun.jna.Native;
|
|
||||||
import com.sun.jna.Pointer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@code NativeLibraryWrapper} implementation for Windows.
|
|
||||||
* <p> This implementation only offers support for the {@code callGetpid} method
|
|
||||||
* using the Windows/Kernel32 library.</p>
|
|
||||||
*
|
|
||||||
* @see org.apache.cassandra.utils.NativeLibraryWrapper
|
|
||||||
* @see NativeLibrary
|
|
||||||
*/
|
|
||||||
@Shared
|
|
||||||
public class NativeLibraryWindows implements NativeLibraryWrapper
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(NativeLibraryWindows.class);
|
|
||||||
|
|
||||||
private static boolean available;
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Native.register(com.sun.jna.NativeLibrary.getInstance("kernel32", Collections.emptyMap()));
|
|
||||||
available = true;
|
|
||||||
}
|
|
||||||
catch (NoClassDefFoundError e)
|
|
||||||
{
|
|
||||||
logger.warn("JNA not found. Native methods will be disabled.");
|
|
||||||
}
|
|
||||||
catch (UnsatisfiedLinkError e)
|
|
||||||
{
|
|
||||||
logger.error("Failed to link the Windows/Kernel32 library against JNA. Native methods will be unavailable.", e);
|
|
||||||
}
|
|
||||||
catch (NoSuchMethodError e)
|
|
||||||
{
|
|
||||||
logger.warn("Obsolete version of JNA present; unable to register Windows/Kernel32 library. Upgrade to JNA 3.2.7 or later");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the process identifier of the calling process (<a href='https://msdn.microsoft.com/en-us/library/windows/desktop/ms683180(v=vs.85).aspx'>GetCurrentProcessId function</a>).
|
|
||||||
*
|
|
||||||
* @return the process identifier of the calling process
|
|
||||||
*/
|
|
||||||
private static native long GetCurrentProcessId() throws LastErrorException;
|
|
||||||
|
|
||||||
public int callMlockall(int flags) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int callMunlockall() throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int callFcntl(int fd, int command, long flags) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int callPosixFadvise(int fd, long offset, int len, int flag) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int callOpen(String path, int flags) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int callFsync(int fd) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int callClose(int fd) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pointer callStrerror(int errnum) throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
throw new UnsatisfiedLinkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the PID of the JVM running
|
|
||||||
* @throws UnsatisfiedLinkError if we fail to link against Sigar
|
|
||||||
* @throws RuntimeException if another unexpected error is thrown by Sigar
|
|
||||||
*/
|
|
||||||
public long callGetpid() throws UnsatisfiedLinkError, RuntimeException
|
|
||||||
{
|
|
||||||
return GetCurrentProcessId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAvailable()
|
|
||||||
{
|
|
||||||
return available;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -113,10 +113,6 @@ public class SigarLibrary
|
||||||
|
|
||||||
private boolean hasAcceptableAddressSpace()
|
private boolean hasAcceptableAddressSpace()
|
||||||
{
|
{
|
||||||
// Check is invalid on Windows
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
long fileMax = sigar.getResourceLimit().getVirtualMemoryMax();
|
long fileMax = sigar.getResourceLimit().getVirtualMemoryMax();
|
||||||
|
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.cassandra.utils;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.sun.jna.LastErrorException;
|
|
||||||
import com.sun.jna.Native;
|
|
||||||
|
|
||||||
public final class WindowsTimer
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(WindowsTimer.class);
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Native.register("winmm");
|
|
||||||
}
|
|
||||||
catch (NoClassDefFoundError e)
|
|
||||||
{
|
|
||||||
logger.warn("JNA not found. winmm.dll cannot be registered. Performance will be negatively impacted on this node.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.error("Failed to register winmm.dll. Performance will be negatively impacted on this node.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static native int timeBeginPeriod(int period) throws LastErrorException;
|
|
||||||
private static native int timeEndPeriod(int period) throws LastErrorException;
|
|
||||||
|
|
||||||
private WindowsTimer() {}
|
|
||||||
|
|
||||||
public static void startTimerPeriod(int period)
|
|
||||||
{
|
|
||||||
if (period == 0)
|
|
||||||
return;
|
|
||||||
assert(period > 0);
|
|
||||||
if (timeBeginPeriod(period) != 0)
|
|
||||||
logger.warn("Failed to set timer to : {}. Performance will be degraded.", period);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void endTimerPeriod(int period)
|
|
||||||
{
|
|
||||||
if (period == 0)
|
|
||||||
return;
|
|
||||||
assert(period > 0);
|
|
||||||
if (timeEndPeriod(period) != 0)
|
|
||||||
logger.warn("Failed to end accelerated timer period. System timer will remain set to: {} ms.", period);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1 @@
|
||||||
cdc_enabled: true
|
cdc_enabled: true
|
||||||
# Compression enabled since uncompressed + cdc isn't compatible w/Windows
|
|
||||||
commitlog_compression:
|
|
||||||
- class_name: LZ4Compressor
|
|
||||||
|
|
|
||||||
|
|
@ -64,11 +64,6 @@ public class DirectorySizerBench
|
||||||
// [java] Statistics: (min, avg, max) = (73.687, 74.714, 76.872), stdev = 0.835
|
// [java] Statistics: (min, avg, max) = (73.687, 74.714, 76.872), stdev = 0.835
|
||||||
// [java] Confidence interval (99.9%): [74.156, 75.272]
|
// [java] Confidence interval (99.9%): [74.156, 75.272]
|
||||||
|
|
||||||
// Throttle CPU on the Windows box to .87GHZ from 4.3GHZ turbo single-core, and #'s for 25600:
|
|
||||||
// [java] Result: 298.628 ▒(99.9%) 14.755 ms/op [Average]
|
|
||||||
// [java] Statistics: (min, avg, max) = (291.245, 298.628, 412.881), stdev = 22.085
|
|
||||||
// [java] Confidence interval (99.9%): [283.873, 313.383]
|
|
||||||
|
|
||||||
// Test w/25,600 files, 100x the load of a full default CommitLog (8192) divided by size (32 per)
|
// Test w/25,600 files, 100x the load of a full default CommitLog (8192) divided by size (32 per)
|
||||||
populateRandomFiles(tempDir, 25600);
|
populateRandomFiles(tempDir, 25600);
|
||||||
sizer = new DirectorySizeCalculator(tempDir);
|
sizer = new DirectorySizeCalculator(tempDir);
|
||||||
|
|
|
||||||
|
|
@ -121,14 +121,6 @@ public class LogbackStatusListener implements StatusListener, LoggerContextListe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Filter out Windows newline
|
|
||||||
if (size() == 2)
|
|
||||||
{
|
|
||||||
byte[] bytes = toByteArray();
|
|
||||||
if (bytes[0] == 0xD && bytes[1] == 0xA)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String statement;
|
String statement;
|
||||||
if (encoding != null)
|
if (encoding != null)
|
||||||
statement = new String(toByteArray(), encoding);
|
statement = new String(toByteArray(), encoding);
|
||||||
|
|
|
||||||
|
|
@ -131,11 +131,10 @@ public final class ServerTestUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup the directories used by the server, creating them if they do not exists.
|
* Cleanup the directories used by the server, creating them if they do not exist.
|
||||||
*/
|
*/
|
||||||
public static void cleanupAndLeaveDirs() throws IOException
|
public static void cleanupAndLeaveDirs() throws IOException
|
||||||
{
|
{
|
||||||
// We need to stop and unmap all CLS instances prior to cleanup() or we'll get failures on Windows.
|
|
||||||
CommitLog.instance.stopUnsafe(true);
|
CommitLog.instance.stopUnsafe(true);
|
||||||
mkdirs(); // Creates the directories if they does not exists
|
mkdirs(); // Creates the directories if they does not exists
|
||||||
cleanup(); // Ensure that the directories are all empty
|
cleanup(); // Ensure that the directories are all empty
|
||||||
|
|
|
||||||
|
|
@ -220,11 +220,6 @@ public class ColumnFamilyStoreTest
|
||||||
@Test
|
@Test
|
||||||
public void testClearEphemeralSnapshots() throws Throwable
|
public void testClearEphemeralSnapshots() throws Throwable
|
||||||
{
|
{
|
||||||
// We don't do snapshot-based repair on Windows so we don't have ephemeral snapshots from repair that need clearing.
|
|
||||||
// This test will fail as we'll revert to the WindowsFailedSnapshotTracker and counts will be off, but since we
|
|
||||||
// don't do snapshot-based repair on Windows, we just skip this test.
|
|
||||||
Assume.assumeTrue(!FBUtilities.isWindows);
|
|
||||||
|
|
||||||
ColumnFamilyStore cfs = Keyspace.open(KEYSPACE1).getColumnFamilyStore(CF_INDEX1);
|
ColumnFamilyStore cfs = Keyspace.open(KEYSPACE1).getColumnFamilyStore(CF_INDEX1);
|
||||||
|
|
||||||
//cleanup any previous test gargbage
|
//cleanup any previous test gargbage
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ import org.apache.cassandra.cql3.QueryProcessor;
|
||||||
import org.apache.cassandra.cql3.UntypedResultSet;
|
import org.apache.cassandra.cql3.UntypedResultSet;
|
||||||
import org.apache.cassandra.dht.ByteOrderedPartitioner.BytesToken;
|
import org.apache.cassandra.dht.ByteOrderedPartitioner.BytesToken;
|
||||||
import org.apache.cassandra.dht.Token;
|
import org.apache.cassandra.dht.Token;
|
||||||
import org.apache.cassandra.schema.SchemaKeyspace;
|
|
||||||
import org.apache.cassandra.transport.ProtocolVersion;
|
import org.apache.cassandra.transport.ProtocolVersion;
|
||||||
import org.apache.cassandra.utils.ByteBufferUtil;
|
import org.apache.cassandra.utils.ByteBufferUtil;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
import org.apache.cassandra.utils.FBUtilities;
|
||||||
|
|
@ -53,9 +52,6 @@ public class SystemKeyspaceTest
|
||||||
{
|
{
|
||||||
DatabaseDescriptor.daemonInitialization();
|
DatabaseDescriptor.daemonInitialization();
|
||||||
CommitLog.instance.start();
|
CommitLog.instance.start();
|
||||||
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
WindowsFailedSnapshotTracker.deleteOldSnapshots();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -98,26 +94,9 @@ public class SystemKeyspaceTest
|
||||||
assert firstId.equals(secondId) : String.format("%s != %s%n", firstId.toString(), secondId.toString());
|
assert firstId.equals(secondId) : String.format("%s != %s%n", firstId.toString(), secondId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertDeletedOrDeferred(int expectedCount)
|
private void assertDeleted()
|
||||||
{
|
{
|
||||||
if (FBUtilities.isWindows)
|
assertTrue(getSystemSnapshotFiles(SchemaConstants.SYSTEM_KEYSPACE_NAME).isEmpty());
|
||||||
assertEquals(expectedCount, getDeferredDeletionCount());
|
|
||||||
else
|
|
||||||
assertTrue(getSystemSnapshotFiles(SchemaConstants.SYSTEM_KEYSPACE_NAME).isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getDeferredDeletionCount()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class c = Class.forName("java.io.DeleteOnExitHook");
|
|
||||||
LinkedHashSet<String> files = (LinkedHashSet<String>)FBUtilities.getProtectedField(c, "files").get(c);
|
|
||||||
return files.size();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -128,15 +107,13 @@ public class SystemKeyspaceTest
|
||||||
cfs.clearUnsafe();
|
cfs.clearUnsafe();
|
||||||
Keyspace.clearSnapshot(null, SchemaConstants.SYSTEM_KEYSPACE_NAME);
|
Keyspace.clearSnapshot(null, SchemaConstants.SYSTEM_KEYSPACE_NAME);
|
||||||
|
|
||||||
int baseline = getDeferredDeletionCount();
|
|
||||||
|
|
||||||
SystemKeyspace.snapshotOnVersionChange();
|
SystemKeyspace.snapshotOnVersionChange();
|
||||||
assertDeletedOrDeferred(baseline);
|
assertDeleted();
|
||||||
|
|
||||||
// now setup system.local as if we're upgrading from a previous version
|
// now setup system.local as if we're upgrading from a previous version
|
||||||
setupReleaseVersion(getOlderVersionString());
|
setupReleaseVersion(getOlderVersionString());
|
||||||
Keyspace.clearSnapshot(null, SchemaConstants.SYSTEM_KEYSPACE_NAME);
|
Keyspace.clearSnapshot(null, SchemaConstants.SYSTEM_KEYSPACE_NAME);
|
||||||
assertDeletedOrDeferred(baseline);
|
assertDeleted();
|
||||||
|
|
||||||
// Compare versions again & verify that snapshots were created for all tables in the system ks
|
// Compare versions again & verify that snapshots were created for all tables in the system ks
|
||||||
SystemKeyspace.snapshotOnVersionChange();
|
SystemKeyspace.snapshotOnVersionChange();
|
||||||
|
|
@ -153,10 +130,9 @@ public class SystemKeyspaceTest
|
||||||
|
|
||||||
SystemKeyspace.snapshotOnVersionChange();
|
SystemKeyspace.snapshotOnVersionChange();
|
||||||
|
|
||||||
// snapshotOnVersionChange for upgrade case will open a SSTR when the CFS is flushed. On Windows, we won't be
|
// snapshotOnVersionChange for upgrade case will open a SSTR when the CFS is flushed.
|
||||||
// able to delete hard-links to that file while segments are memory-mapped, so they'll be marked for deferred deletion.
|
|
||||||
// 10 files expected.
|
// 10 files expected.
|
||||||
assertDeletedOrDeferred(baseline + 10);
|
assertDeleted();
|
||||||
|
|
||||||
Keyspace.clearSnapshot(null, SchemaConstants.SYSTEM_KEYSPACE_NAME);
|
Keyspace.clearSnapshot(null, SchemaConstants.SYSTEM_KEYSPACE_NAME);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.cassandra.db.commitlog;
|
|
||||||
|
|
||||||
import org.junit.Assume;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import org.apache.cassandra.SchemaLoader;
|
|
||||||
import org.apache.cassandra.Util;
|
|
||||||
import org.apache.cassandra.schema.TableMetadata;
|
|
||||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
|
||||||
import org.apache.cassandra.db.ColumnFamilyStore;
|
|
||||||
import org.apache.cassandra.db.DecoratedKey;
|
|
||||||
import org.apache.cassandra.db.Keyspace;
|
|
||||||
import org.apache.cassandra.db.RowUpdateBuilder;
|
|
||||||
import org.apache.cassandra.db.WindowsFailedSnapshotTracker;
|
|
||||||
import org.apache.cassandra.io.sstable.SnapshotDeletingTask;
|
|
||||||
import org.apache.cassandra.schema.KeyspaceParams;
|
|
||||||
import org.apache.cassandra.service.GCInspector;
|
|
||||||
import org.apache.cassandra.utils.ByteBufferUtil;
|
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
|
|
||||||
public class SnapshotDeletingTest
|
|
||||||
{
|
|
||||||
private static final String KEYSPACE1 = "Keyspace1";
|
|
||||||
private static final String CF_STANDARD1 = "CF_STANDARD1";
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void defineSchema() throws Exception
|
|
||||||
{
|
|
||||||
DatabaseDescriptor.daemonInitialization();
|
|
||||||
GCInspector.register();
|
|
||||||
// Needed to init the output file where we print failed snapshots. This is called on node startup.
|
|
||||||
WindowsFailedSnapshotTracker.deleteOldSnapshots();
|
|
||||||
SchemaLoader.prepareServer();
|
|
||||||
SchemaLoader.createKeyspace(KEYSPACE1,
|
|
||||||
KeyspaceParams.simple(1),
|
|
||||||
SchemaLoader.standardCFMD(KEYSPACE1, CF_STANDARD1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCompactionHook() throws Exception
|
|
||||||
{
|
|
||||||
Assume.assumeTrue(FBUtilities.isWindows);
|
|
||||||
|
|
||||||
Keyspace keyspace = Keyspace.open(KEYSPACE1);
|
|
||||||
ColumnFamilyStore store = keyspace.getColumnFamilyStore(CF_STANDARD1);
|
|
||||||
store.clearUnsafe();
|
|
||||||
|
|
||||||
populate(10000);
|
|
||||||
store.snapshot("snapshot1");
|
|
||||||
|
|
||||||
// Confirm snapshot deletion fails. Sleep for a bit just to make sure the SnapshotDeletingTask has
|
|
||||||
// time to run and fail.
|
|
||||||
Thread.sleep(500);
|
|
||||||
store.clearSnapshot("snapshot1");
|
|
||||||
assertEquals(1, SnapshotDeletingTask.pendingDeletionCount());
|
|
||||||
|
|
||||||
// Compact the cf and confirm that the executor's after hook calls rescheduleDeletion
|
|
||||||
populate(20000);
|
|
||||||
store.forceBlockingFlush();
|
|
||||||
store.forceMajorCompaction();
|
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
while (System.currentTimeMillis() - start < 1000 && SnapshotDeletingTask.pendingDeletionCount() > 0)
|
|
||||||
{
|
|
||||||
Thread.yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(0, SnapshotDeletingTask.pendingDeletionCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populate(int rowCount) {
|
|
||||||
long timestamp = System.currentTimeMillis();
|
|
||||||
TableMetadata cfm = Keyspace.open(KEYSPACE1).getColumnFamilyStore(CF_STANDARD1).metadata();
|
|
||||||
for (int i = 0; i <= rowCount; i++)
|
|
||||||
{
|
|
||||||
DecoratedKey key = Util.dk(Integer.toString(i));
|
|
||||||
for (int j = 0; j < 10; j++)
|
|
||||||
{
|
|
||||||
new RowUpdateBuilder(cfm, timestamp, 0, key.getKey())
|
|
||||||
.clustering(Integer.toString(j))
|
|
||||||
.add("val", ByteBufferUtil.EMPTY_BYTE_BUFFER)
|
|
||||||
.build()
|
|
||||||
.applyUnsafe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1290,8 +1290,7 @@ public class LogTransactionTest extends AbstractTransactionalTest
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check either that a temporary file is expected to exist (in the existingFiles) or that
|
// Check either that a temporary file is expected to exist (in the existingFiles) or that
|
||||||
// it does not exist any longer (on Windows we need to check File.exists() because a list
|
// it does not exist any longer.
|
||||||
// might return a file as existing even if it does not)
|
|
||||||
private static void assertFiles(Iterable<String> existingFiles, Set<File> temporaryFiles)
|
private static void assertFiles(Iterable<String> existingFiles, Set<File> temporaryFiles)
|
||||||
{
|
{
|
||||||
for (String filePath : existingFiles)
|
for (String filePath : existingFiles)
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ public class SSTableLoaderTest
|
||||||
FileUtils.deleteRecursive(tmpdir);
|
FileUtils.deleteRecursive(tmpdir);
|
||||||
} catch (FSWriteError e) {
|
} catch (FSWriteError e) {
|
||||||
/*
|
/*
|
||||||
Windows does not allow a mapped file to be deleted, so we probably forgot to clean the buffers somewhere.
|
|
||||||
We force a GC here to force buffer deallocation, and then try deleting the directory again.
|
We force a GC here to force buffer deallocation, and then try deleting the directory again.
|
||||||
For more information, see: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4715154
|
For more information, see: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4715154
|
||||||
If this is not the problem, the exception will be rethrown anyway.
|
If this is not the problem, the exception will be rethrown anyway.
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ import org.apache.cassandra.db.rows.*;
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
|
import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.fail;
|
import static junit.framework.Assert.fail;
|
||||||
import static org.apache.cassandra.service.ActiveRepairService.NO_PENDING_REPAIR;
|
import static org.apache.cassandra.service.ActiveRepairService.NO_PENDING_REPAIR;
|
||||||
|
|
@ -44,7 +43,7 @@ import static org.junit.Assert.assertTrue;
|
||||||
public class SSTableWriterTest extends SSTableWriterTestBase
|
public class SSTableWriterTest extends SSTableWriterTestBase
|
||||||
{
|
{
|
||||||
@Test
|
@Test
|
||||||
public void testAbortTxnWithOpenEarlyShouldRemoveSSTable() throws InterruptedException
|
public void testAbortTxnWithOpenEarlyShouldRemoveSSTable()
|
||||||
{
|
{
|
||||||
Keyspace keyspace = Keyspace.open(KEYSPACE);
|
Keyspace keyspace = Keyspace.open(KEYSPACE);
|
||||||
ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(CF);
|
ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(CF);
|
||||||
|
|
@ -81,13 +80,9 @@ public class SSTableWriterTest extends SSTableWriterTestBase
|
||||||
int datafiles = assertFileCounts(dir.tryListNames());
|
int datafiles = assertFileCounts(dir.tryListNames());
|
||||||
assertEquals(datafiles, 1);
|
assertEquals(datafiles, 1);
|
||||||
|
|
||||||
// These checks don't work on Windows because the writer has the channel still
|
LifecycleTransaction.waitForDeletions();
|
||||||
// open till .abort() is called (via the builder)
|
assertFileCounts(dir.tryListNames());
|
||||||
if (!FBUtilities.isWindows)
|
|
||||||
{
|
|
||||||
LifecycleTransaction.waitForDeletions();
|
|
||||||
assertFileCounts(dir.tryListNames());
|
|
||||||
}
|
|
||||||
writer.abort();
|
writer.abort();
|
||||||
txn.abort();
|
txn.abort();
|
||||||
LifecycleTransaction.waitForDeletions();
|
LifecycleTransaction.waitForDeletions();
|
||||||
|
|
@ -130,13 +125,9 @@ public class SSTableWriterTest extends SSTableWriterTestBase
|
||||||
assertEquals(datafiles, 1);
|
assertEquals(datafiles, 1);
|
||||||
|
|
||||||
sstable.selfRef().release();
|
sstable.selfRef().release();
|
||||||
// These checks don't work on Windows because the writer has the channel still
|
|
||||||
// open till .abort() is called (via the builder)
|
LifecycleTransaction.waitForDeletions();
|
||||||
if (!FBUtilities.isWindows)
|
assertFileCounts(dir.tryListNames());
|
||||||
{
|
|
||||||
LifecycleTransaction.waitForDeletions();
|
|
||||||
assertFileCounts(dir.tryListNames());
|
|
||||||
}
|
|
||||||
|
|
||||||
txn.abort();
|
txn.abort();
|
||||||
LifecycleTransaction.waitForDeletions();
|
LifecycleTransaction.waitForDeletions();
|
||||||
|
|
@ -184,13 +175,9 @@ public class SSTableWriterTest extends SSTableWriterTestBase
|
||||||
int datafiles = assertFileCounts(dir.tryListNames());
|
int datafiles = assertFileCounts(dir.tryListNames());
|
||||||
assertEquals(datafiles, 2);
|
assertEquals(datafiles, 2);
|
||||||
|
|
||||||
// These checks don't work on Windows because the writer has the channel still
|
LifecycleTransaction.waitForDeletions();
|
||||||
// open till .abort() is called (via the builder)
|
assertFileCounts(dir.tryListNames());
|
||||||
if (!FBUtilities.isWindows)
|
|
||||||
{
|
|
||||||
LifecycleTransaction.waitForDeletions();
|
|
||||||
assertFileCounts(dir.tryListNames());
|
|
||||||
}
|
|
||||||
txn.abort();
|
txn.abort();
|
||||||
LifecycleTransaction.waitForDeletions();
|
LifecycleTransaction.waitForDeletions();
|
||||||
datafiles = assertFileCounts(dir.tryListNames());
|
datafiles = assertFileCounts(dir.tryListNames());
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
||||||
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
||||||
import org.apache.cassandra.schema.KeyspaceParams;
|
import org.apache.cassandra.schema.KeyspaceParams;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
@ -67,15 +66,6 @@ public class SSTableWriterTestBase extends SchemaLoader
|
||||||
{
|
{
|
||||||
DatabaseDescriptor.daemonInitialization();
|
DatabaseDescriptor.daemonInitialization();
|
||||||
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
{
|
|
||||||
standardMode = DatabaseDescriptor.getDiskAccessMode();
|
|
||||||
indexMode = DatabaseDescriptor.getIndexAccessMode();
|
|
||||||
|
|
||||||
DatabaseDescriptor.setDiskAccessMode(Config.DiskAccessMode.standard);
|
|
||||||
DatabaseDescriptor.setIndexAccessMode(Config.DiskAccessMode.standard);
|
|
||||||
}
|
|
||||||
|
|
||||||
SchemaLoader.prepareServer();
|
SchemaLoader.prepareServer();
|
||||||
SchemaLoader.createKeyspace(KEYSPACE,
|
SchemaLoader.createKeyspace(KEYSPACE,
|
||||||
KeyspaceParams.simple(1),
|
KeyspaceParams.simple(1),
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,12 @@ import java.util.Set;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.apache.cassandra.config.Config;
|
|
||||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||||
import org.apache.cassandra.dht.IPartitioner;
|
import org.apache.cassandra.dht.IPartitioner;
|
||||||
import org.apache.cassandra.dht.Murmur3Partitioner;
|
import org.apache.cassandra.dht.Murmur3Partitioner;
|
||||||
import org.apache.cassandra.dht.Range;
|
import org.apache.cassandra.dht.Range;
|
||||||
import org.apache.cassandra.dht.Token;
|
import org.apache.cassandra.dht.Token;
|
||||||
import org.apache.cassandra.repair.RepairParallelism;
|
import org.apache.cassandra.repair.RepairParallelism;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
@ -52,11 +50,7 @@ public class RepairOptionTest
|
||||||
|
|
||||||
// parse with empty options
|
// parse with empty options
|
||||||
RepairOption option = RepairOption.parse(new HashMap<String, String>(), partitioner);
|
RepairOption option = RepairOption.parse(new HashMap<String, String>(), partitioner);
|
||||||
|
assertTrue(option.getParallelism() == RepairParallelism.SEQUENTIAL);
|
||||||
if (FBUtilities.isWindows && (DatabaseDescriptor.getDiskAccessMode() != Config.DiskAccessMode.standard || DatabaseDescriptor.getIndexAccessMode() != Config.DiskAccessMode.standard))
|
|
||||||
assertTrue(option.getParallelism() == RepairParallelism.PARALLEL);
|
|
||||||
else
|
|
||||||
assertTrue(option.getParallelism() == RepairParallelism.SEQUENTIAL);
|
|
||||||
|
|
||||||
assertFalse(option.isPrimaryRange());
|
assertFalse(option.isPrimaryRange());
|
||||||
assertFalse(option.isIncremental());
|
assertFalse(option.isIncremental());
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,7 @@
|
||||||
|
|
||||||
package org.apache.cassandra.service;
|
package org.apache.cassandra.service;
|
||||||
|
|
||||||
import org.apache.cassandra.io.util.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -37,7 +35,6 @@ import org.junit.Test;
|
||||||
import org.apache.cassandra.audit.AuditLogManager;
|
import org.apache.cassandra.audit.AuditLogManager;
|
||||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||||
import org.apache.cassandra.db.Keyspace;
|
import org.apache.cassandra.db.Keyspace;
|
||||||
import org.apache.cassandra.db.WindowsFailedSnapshotTracker;
|
|
||||||
import org.apache.cassandra.db.commitlog.CommitLog;
|
import org.apache.cassandra.db.commitlog.CommitLog;
|
||||||
import org.apache.cassandra.dht.Murmur3Partitioner;
|
import org.apache.cassandra.dht.Murmur3Partitioner;
|
||||||
import org.apache.cassandra.dht.Murmur3Partitioner.LongToken;
|
import org.apache.cassandra.dht.Murmur3Partitioner.LongToken;
|
||||||
|
|
@ -53,13 +50,11 @@ import org.apache.cassandra.locator.InetAddressAndPort;
|
||||||
import org.apache.cassandra.locator.PropertyFileSnitch;
|
import org.apache.cassandra.locator.PropertyFileSnitch;
|
||||||
import org.apache.cassandra.locator.TokenMetadata;
|
import org.apache.cassandra.locator.TokenMetadata;
|
||||||
import org.apache.cassandra.schema.*;
|
import org.apache.cassandra.schema.*;
|
||||||
import org.apache.cassandra.io.util.FileWriter;
|
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
import org.apache.cassandra.utils.FBUtilities;
|
||||||
import org.assertj.core.api.Assertions;
|
import org.assertj.core.api.Assertions;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assume.assumeTrue;
|
|
||||||
|
|
||||||
public class StorageServiceServerTest
|
public class StorageServiceServerTest
|
||||||
{
|
{
|
||||||
|
|
@ -88,75 +83,6 @@ public class StorageServiceServerTest
|
||||||
StorageService.instance.takeSnapshot(UUID.randomUUID().toString());
|
StorageService.instance.takeSnapshot(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTempFilePresence(File f, boolean exist)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
File subdir = new File(f, Integer.toString(i));
|
|
||||||
subdir.tryCreateDirectory();
|
|
||||||
for (int j = 0; j < 5; j++)
|
|
||||||
{
|
|
||||||
File subF = new File(subdir, Integer.toString(j));
|
|
||||||
assert(exist ? subF.exists() : !subF.exists());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSnapshotFailureHandler() throws IOException
|
|
||||||
{
|
|
||||||
assumeTrue(FBUtilities.isWindows);
|
|
||||||
|
|
||||||
// Initial "run" of Cassandra, nothing in failed snapshot file
|
|
||||||
WindowsFailedSnapshotTracker.deleteOldSnapshots();
|
|
||||||
|
|
||||||
File f = new File(System.getenv("TEMP") + File.pathSeparator() + Integer.toString(new Random().nextInt()));
|
|
||||||
f.tryCreateDirectory();
|
|
||||||
f.deleteOnExit();
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
File subdir = new File(f, Integer.toString(i));
|
|
||||||
subdir.tryCreateDirectory();
|
|
||||||
for (int j = 0; j < 5; j++)
|
|
||||||
new File(subdir, Integer.toString(j)).createFileIfNotExists();
|
|
||||||
}
|
|
||||||
|
|
||||||
checkTempFilePresence(f, true);
|
|
||||||
|
|
||||||
// Confirm deletion is recursive
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
WindowsFailedSnapshotTracker.handleFailedSnapshot(new File(f, Integer.toString(i)));
|
|
||||||
|
|
||||||
assertTrue(new File(WindowsFailedSnapshotTracker.TODELETEFILE).exists());
|
|
||||||
|
|
||||||
// Simulate shutdown and restart of C* node, closing out the list of failed snapshots.
|
|
||||||
WindowsFailedSnapshotTracker.resetForTests();
|
|
||||||
|
|
||||||
// Perform new run, mimicking behavior of C* at startup
|
|
||||||
WindowsFailedSnapshotTracker.deleteOldSnapshots();
|
|
||||||
checkTempFilePresence(f, false);
|
|
||||||
|
|
||||||
// Check to make sure we don't delete non-temp, non-datafile locations
|
|
||||||
WindowsFailedSnapshotTracker.resetForTests();
|
|
||||||
PrintWriter tempPrinter = new PrintWriter(new FileWriter(new File(WindowsFailedSnapshotTracker.TODELETEFILE), File.WriteMode.APPEND));
|
|
||||||
tempPrinter.println(".safeDir");
|
|
||||||
tempPrinter.close();
|
|
||||||
|
|
||||||
File protectedDir = new File(".safeDir");
|
|
||||||
protectedDir.tryCreateDirectory();
|
|
||||||
File protectedFile = new File(protectedDir, ".safeFile");
|
|
||||||
protectedFile.createFileIfNotExists();
|
|
||||||
|
|
||||||
WindowsFailedSnapshotTracker.handleFailedSnapshot(protectedDir);
|
|
||||||
WindowsFailedSnapshotTracker.deleteOldSnapshots();
|
|
||||||
|
|
||||||
assertTrue(protectedDir.exists());
|
|
||||||
assertTrue(protectedFile.exists());
|
|
||||||
|
|
||||||
protectedFile.tryDelete();
|
|
||||||
protectedDir.tryDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTableSnapshot() throws IOException
|
public void testTableSnapshot() throws IOException
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@ public class MonotonicClockTest
|
||||||
nowNanos = Math.max(nowNanos, nanoTime());
|
nowNanos = Math.max(nowNanos, nanoTime());
|
||||||
long convertedNow = approxTime.translate().toMillisSinceEpoch(nowNanos);
|
long convertedNow = approxTime.translate().toMillisSinceEpoch(nowNanos);
|
||||||
|
|
||||||
int maxDiff = FBUtilities.isWindows ? 15 : 1;
|
int maxDiff = 1;
|
||||||
assertTrue("convertedNow = " + convertedNow + " lastConverted = " + lastConverted + " in iteration " + ii,
|
assertTrue("convertedNow = " + convertedNow + " lastConverted = " + lastConverted + " in iteration " + ii,
|
||||||
convertedNow >= (lastConverted - maxDiff));
|
convertedNow >= (lastConverted - maxDiff));
|
||||||
|
|
||||||
maxDiff = FBUtilities.isWindows ? 25 : 2;
|
maxDiff = 2;
|
||||||
assertTrue("now = " + now + " convertedNow = " + convertedNow + " in iteration " + ii,
|
assertTrue("now = " + now + " convertedNow = " + convertedNow + " in iteration " + ii,
|
||||||
(maxDiff - 2) <= convertedNow);
|
(maxDiff - 2) <= convertedNow);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ import java.net.SocketException;
|
||||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||||
import org.apache.cassandra.stress.settings.StressSettings;
|
import org.apache.cassandra.stress.settings.StressSettings;
|
||||||
import org.apache.cassandra.stress.util.MultiResultLogger;
|
import org.apache.cassandra.stress.util.MultiResultLogger;
|
||||||
import org.apache.cassandra.utils.FBUtilities;
|
|
||||||
import org.apache.cassandra.utils.WindowsTimer;
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
public final class Stress
|
public final class Stress
|
||||||
|
|
@ -57,18 +55,9 @@ public final class Stress
|
||||||
|
|
||||||
public static void main(String[] arguments) throws Exception
|
public static void main(String[] arguments) throws Exception
|
||||||
{
|
{
|
||||||
if (FBUtilities.isWindows)
|
System.exit(run(arguments));
|
||||||
WindowsTimer.startTimerPeriod(1);
|
|
||||||
|
|
||||||
int exitCode = run(arguments);
|
|
||||||
|
|
||||||
if (FBUtilities.isWindows)
|
|
||||||
WindowsTimer.endTimerPeriod(1);
|
|
||||||
|
|
||||||
System.exit(exitCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static int run(String[] arguments)
|
private static int run(String[] arguments)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue