mirror of https://github.com/apache/cassandra
Docs: Revise and fix leftnav and links
Fix leftnav xrefs, cass-stress change, move virtualtables, add index.adoc for each topic Fix xrefs and headers, fix gen-nodetool script to point to new locations, fix links, headers and errors. Cleaned up installing instructions. patch by Lorina Poland; reviewed by Mick Semb Wever for CASSANDRA-18606
This commit is contained in:
parent
51018940f6
commit
1e2c88fff8
|
|
@ -12,7 +12,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
GENERATE_NODETOOL_DOCS = ./scripts/gen-nodetool-docs.py
|
||||
MAKE_CASSANDRA_YAML = ./scripts/convert_yaml_to_adoc.py ../conf/cassandra.yaml ./modules/cassandra/pages/configuration/cass_yaml_file.adoc
|
||||
MAKE_CASSANDRA_YAML = ./scripts/convert_yaml_to_adoc.py ../conf/cassandra.yaml ./modules/cassandra/pages/managing/configuration/cass_yaml_file.adoc
|
||||
|
||||
.PHONY: html
|
||||
html:
|
||||
|
|
@ -20,7 +20,7 @@ html:
|
|||
|
||||
.PHONY: gen-asciidoc
|
||||
gen-asciidoc:
|
||||
@mkdir -p modules/cassandra/pages/tools/nodetool
|
||||
@mkdir -p modules/cassandra/pages/managing/tools/nodetool
|
||||
@mkdir -p modules/cassandra/examples/TEXT/NODETOOL
|
||||
python3 $(GENERATE_NODETOOL_DOCS)
|
||||
python3 $(MAKE_CASSANDRA_YAML)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
= Welcome to Apache Cassandra's documentation!
|
||||
|
||||
:description: Starting page for Apache Cassandra documentation.
|
||||
:keywords: Apache, Cassandra, NoSQL, database
|
||||
:cass-url: http://cassandra.apache.org
|
||||
:cass-contrib-url: https://wiki.apache.org/cassandra/HowToContribute
|
||||
|
||||
This is the official documentation for {cass-url}[Apache Cassandra].
|
||||
If you would like to contribute to this documentation, you are welcome
|
||||
to do so by submitting your contribution like any other patch following
|
||||
{cass-contrib-url}[these instructions].
|
||||
This is the official documentation for {cass-url}[Apache Cassandra].
|
||||
If you would like to contribute to this documentation, you are welcome to do so by submitting your contribution like any other patch following {cass-contrib-url}[these instructions].
|
||||
|
||||
== Main documentation
|
||||
|
||||
|
|
@ -38,10 +35,10 @@ to do so by submitting your contribution like any other patch following
|
|||
| xref:cassandra:integrating/plugins/index.adoc[Plug-ins] | Third-party plug-ins
|
||||
|
||||
| xref:master@_:ROOT:native_protocol.adoc[Native Protocols] | Native Cassandra protocol specifications
|
||||
|
||||
|===
|
||||
|
||||
== Meta information
|
||||
|
||||
* xref:master@_:ROOT:bugs.adoc[Reporting bugs]
|
||||
* xref:master@_:ROOT:contactus.adoc[Contact us]
|
||||
* xref:master@_:ROOT:development/index.adoc[Contributing code]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
openjdk version "1.8.0_222"
|
||||
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~16.04.1-b10)
|
||||
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
|
||||
openjdk version "11.0.20" 2023-07-18
|
||||
OpenJDK Runtime Environment Temurin-11.0.20+8 (build 11.0.20+8)
|
||||
OpenJDK 64-Bit Server VM Temurin-11.0.20+8 (build 11.0.20+8, mixed mode)
|
||||
|
|
@ -1,92 +1,94 @@
|
|||
* Cassandra
|
||||
** xref:getting-started/index.adoc[Getting Started]
|
||||
*** xref:installing/installing.adoc[Installing Cassandra]
|
||||
*** xref:getting-started/configuring.adoc[Configuring Cassandra]
|
||||
*** xref:getting-started/querying.adoc[Inserting and querying]
|
||||
*** xref:getting-started/drivers.adoc[Client drivers]
|
||||
*** xref:getting-started/java11.adoc[Support for Java 11]
|
||||
*** xref:getting-started/production.adoc[Production recommendations]
|
||||
|
||||
** xref:new/index.adoc[What's new]
|
||||
|
||||
** xref:architecture/index.adoc[Architecture]
|
||||
*** xref:architecture/overview.adoc[Overview]
|
||||
*** xref:architecture/dynamo.adoc[Dynamo]
|
||||
*** xref:architecture/storage-engine.adoc[Storage engine]
|
||||
*** xref:architecture/guarantees.adoc[Guarantees]
|
||||
*** xref:architecture/messaging.adoc[Improved internode messaging]
|
||||
*** xref:architecture/streaming.adoc[Improved streaming]
|
||||
|
||||
** xref:developing:data-modeling/index.adoc[Data modeling]
|
||||
*** xref:developing:data-modeling/intro.adoc[Introduction]
|
||||
*** xref:developing:data-modeling/data-modeling_conceptual.adoc[Conceptual data modeling]
|
||||
*** xref:developing:data-modeling/data-modeling_rdbms.adoc[RDBMS design]
|
||||
*** xref:developing:data-modeling/data-modeling_queries.adoc[Defining application queries]
|
||||
*** xref:developing:data-modeling/data-modeling_logical.adoc[Logical data modeling]
|
||||
*** xref:developing:data-modeling/data-modeling_physical.adoc[Physical data modeling]
|
||||
*** xref:developing:data-modeling/data-modeling_refining.adoc[Evaluating and refining data models]
|
||||
*** xref:developing:data-modeling/data-modeling_schema.adoc[Defining database schema]
|
||||
*** xref:developing:data-modeling/data-modeling_tools.adoc[Cassandra data modeling tools]
|
||||
|
||||
** xref:developing:cql/index.adoc[Cassandra Query Language (CQL)]
|
||||
*** xref:developing:cql/definitions.adoc[Definitions]
|
||||
*** xref:developing:cql/types.adoc[Data types]
|
||||
*** xref:developing:cql/ddl.adoc[Data definition (DDL)]
|
||||
*** xref:developing:cql/dml.adoc[Data manipulation (DML)]
|
||||
*** xref:developing:cql/operators.adoc[Operators]
|
||||
*** xref:developing:cql/indexes.adoc[Secondary indexes]
|
||||
*** xref:developing:cql/mvs.adoc[Materialized views]
|
||||
*** xref:developing:cql/functions.adoc[Functions]
|
||||
*** xref:developing:cql/json.adoc[JSON]
|
||||
*** xref:developing:cql/security.adoc[Security]
|
||||
*** xref:developing:cql/triggers.adoc[Triggers]
|
||||
*** xref:developing:cql/appendices.adoc[Appendices]
|
||||
*** xref:developing:cql/changes.adoc[Changes]
|
||||
*** xref:developing:cql/SASI.adoc[SASI]
|
||||
*** xref:developing:cql/cql_singlefile.adoc[Single file of CQL information]
|
||||
|
||||
** xref:managing:configuration/index.adoc[Configuration]
|
||||
*** xref:managing:configuration/cass_yaml_file.adoc[cassandra.yaml]
|
||||
*** xref:managing:configuration/cass_rackdc_file.adoc[cassandra-rackdc.properties]
|
||||
*** xref:managing:configuration/cass_env_sh_file.adoc[cassandra-env.sh]
|
||||
*** xref:managing:configuration/cass_topo_file.adoc[cassandra-topologies.properties]
|
||||
*** xref:managing:configuration/cass_cl_archive_file.adoc[commitlog-archiving.properties]
|
||||
*** xref:managing:configuration/cass_logback_xml_file.adoc[logback.xml]
|
||||
*** xref:managing:configuration/cass_jvm_options_file.adoc[jvm-* files]
|
||||
*** xref:managing:configuration/configuration.adoc[Liberating cassandra.yaml Parameters' Names from Their Units]
|
||||
|
||||
** xref:managing:operating/index.adoc[Operating]
|
||||
*** xref:managing:operating/snitch.adoc[Snitches]
|
||||
*** xref:managing:operating/topo_changes.adoc[Topology changes]
|
||||
*** xref:managing:operating/repair.adoc[Repair]
|
||||
*** xref:managing:operating/read_repair.adoc[Read repair]
|
||||
*** xref:managing:operating/hints.adoc[Hints]
|
||||
*** xref:managing:operating/bloom_filters.adoc[Bloom filters]
|
||||
*** xref:managing:operating/compression.adoc[Compression]
|
||||
*** xref:managing:operating/cdc.adoc[Change Data Capture (CDC)]
|
||||
*** xref:managing:operating/backups.adoc[Backups]
|
||||
*** xref:managing:operating/bulk_loading.adoc[Bulk loading]
|
||||
*** xref:managing:operating/metrics.adoc[Metrics]
|
||||
*** xref:managing:operating/security.adoc[Security]
|
||||
*** xref:managing:operating/hardware.adoc[Hardware]
|
||||
*** xref:managing:operating/compaction/index.adoc[Compaction]
|
||||
*** xref:managing:operating/virtualtables.adoc[Virtual tables]
|
||||
*** xref:managing:operating/auditlogging.adoc[Audit logging]
|
||||
*** xref:managing:operating/audit_logging.adoc[Audit logging 2]
|
||||
*** xref:managing:operating/fqllogging.adoc[Full query logging]
|
||||
*** xref:managing:operating/transientreplication.adoc[Transient replication]
|
||||
|
||||
** xref:managing:tools/index.adoc[Tools]
|
||||
*** xref:managing:tools/cqlsh.adoc[cqlsh: the CQL shell]
|
||||
*** xref:managing:tools/nodetool/nodetool.adoc[nodetool]
|
||||
*** xref:managing:tools/sstable/index.adoc[SSTable tools]
|
||||
*** xref:managing:tools/cassandra_stress.adoc[cassandra-stress]
|
||||
|
||||
** xref:troubleshooting/index.adoc[Troubleshooting]
|
||||
*** xref:troubleshooting/finding_nodes.adoc[Finding misbehaving nodes]
|
||||
*** xref:troubleshooting/reading_logs.adoc[Reading Cassandra logs]
|
||||
*** xref:troubleshooting/use_nodetool.adoc[Using nodetool]
|
||||
*** xref:troubleshooting/use_tools.adoc[Using external tools to deep-dive]
|
||||
** xref:cassandra:new/index.adoc[]
|
||||
** xref:cassandra:overview/index.adoc[]
|
||||
*** xref:cassandra:overview/terminology.adoc[]
|
||||
*** xref:cassandra:overview/faq/index.adoc[]
|
||||
** xref:cassandra:getting-started/index.adoc[]
|
||||
*** xref:cassandra:installing/installing.adoc[]
|
||||
*** xref:cassandra:getting-started/configuring.adoc[]
|
||||
*** xref:cassandra:getting-started/querying.adoc[]
|
||||
*** xref:cassandra:getting-started/drivers.adoc[]
|
||||
*** xref:cassandra:getting-started/java11.adoc[]
|
||||
*** xref:cassandra:getting-started/production.adoc[]
|
||||
** xref:cassandra:architecture/index.adoc[]
|
||||
*** xref:cassandra:architecture/overview.adoc[]
|
||||
*** xref:cassandra:architecture/dynamo.adoc[]
|
||||
*** xref:cassandra:architecture/storage-engine.adoc[]
|
||||
*** xref:cassandra:architecture/guarantees.adoc[]
|
||||
*** xref:cassandra:architecture/messaging.adoc[]
|
||||
*** xref:cassandra:architecture/streaming.adoc[]
|
||||
** xref:cassandra:installing/installing.adoc[]
|
||||
** xref:cassandra:developing/index.adoc[]
|
||||
*** xref:cassandra:developing/data-modeling/index.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/intro.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_conceptual.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_rdbms.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_queries.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_logical.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_physical.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_refining.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_schema.adoc[]
|
||||
**** xref:cassandra:developing/data-modeling/data-modeling_tools.adoc[]
|
||||
*** xref:cassandra:developing/cql/index.adoc[]
|
||||
**** xref:cassandra:developing/cql/definitions.adoc[]
|
||||
**** xref:cassandra:developing/cql/types.adoc[]
|
||||
**** xref:cassandra:developing/cql/ddl.adoc[]
|
||||
**** xref:cassandra:developing/cql/dml.adoc[]
|
||||
**** xref:cassandra:developing/cql/operators.adoc[]
|
||||
**** xref:cassandra:developing/cql/indexes.adoc[]
|
||||
**** xref:cassandra:developing/cql/mvs.adoc[]
|
||||
**** xref:cassandra:developing/cql/functions.adoc[]
|
||||
**** xref:cassandra:developing/cql/json.adoc[]
|
||||
**** xref:cassandra:developing/cql/security.adoc[]
|
||||
**** xref:cassandra:developing/cql/triggers.adoc[]
|
||||
**** xref:cassandra:developing/cql/appendices.adoc[]
|
||||
**** xref:cassandra:developing/cql/changes.adoc[]
|
||||
**** xref:cassandra:developing/cql/SASI.adoc[SASI]
|
||||
**** xref:cassandra:developing/cql/cql_singlefile.adoc[]
|
||||
** xref:cassandra:integrating/plugins/index.adoc[Plug-ins]
|
||||
** xref:cassandra:managing/index.adoc[]
|
||||
*** xref:cassandra:managing/configuration/index.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_yaml_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_rackdc_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_env_sh_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_topo_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_cl_archive_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_logback_xml_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/cass_jvm_options_file.adoc[]
|
||||
**** xref:cassandra:managing/configuration/configuration.adoc[]
|
||||
*** xref:cassandra:managing/operating/index.adoc[]
|
||||
**** xref:cassandra:managing/operating/snitch.adoc[]
|
||||
**** xref:cassandra:managing/operating/topo_changes.adoc[]
|
||||
**** xref:cassandra:managing/operating/repair.adoc[]
|
||||
**** xref:cassandra:managing/operating/read_repair.adoc[]
|
||||
**** xref:cassandra:managing/operating/hints.adoc[]
|
||||
**** xref:cassandra:managing/operating/bloom_filters.adoc[]
|
||||
**** xref:cassandra:managing/operating/compression.adoc[]
|
||||
**** xref:cassandra:managing/operating/cdc.adoc[]
|
||||
**** xref:cassandra:managing/operating/backups.adoc[]
|
||||
**** xref:cassandra:managing/operating/bulk_loading.adoc[]
|
||||
**** xref:cassandra:managing/operating/metrics.adoc[]
|
||||
**** xref:cassandra:managing/operating/security.adoc[]
|
||||
**** xref:cassandra:managing/operating/hardware.adoc[]
|
||||
**** xref:cassandra:managing/operating/compaction/index.adoc[]
|
||||
**** xref:cassandra:managing/operating/virtualtables.adoc[]
|
||||
**** xref:cassandra:managing/operating/auditlogging.adoc[]
|
||||
**** xref:cassandra:managing/operating/audit_logging.adoc[]
|
||||
**** xref:cassandra:managing/operating/fqllogging.adoc[]
|
||||
**** xref:cassandra:managing/operating/transientreplication.adoc[]
|
||||
*** xref:cassandra:managing/tools/index.adoc[]
|
||||
**** xref:cassandra:managing/tools/cqlsh.adoc[]
|
||||
**** xref:cassandra:managing/tools/nodetool/nodetool.adoc[]
|
||||
**** xref:cassandra:managing/tools/sstable/index.adoc[]
|
||||
** xref:cassandra:tooling/index.adoc[]
|
||||
*** xref:cassandra:tooling/hash-password.adoc[]
|
||||
*** xref:cassandra:tooling/generate-tokens.adoc[]
|
||||
*** xref:cassandra:tooling/cassandra-stress.adoc[]
|
||||
** xref:cassandra:troubleshooting/index.adoc[]
|
||||
*** xref:cassandra:troubleshooting/finding_nodes.adoc[]
|
||||
*** xref:cassandra:troubleshooting/reading_logs.adoc[]
|
||||
*** xref:cassandra:troubleshooting/use_nodetool.adoc[]
|
||||
*** xref:cassandra:troubleshooting/use_tools.adoc[]
|
||||
|
||||
** xref:master@_:ROOT:development/index.adoc[Development]
|
||||
*** xref:master@_:ROOT:development/gettingstarted.adoc[Getting started]
|
||||
|
|
@ -99,9 +101,4 @@
|
|||
*** xref:master@_:ROOT:development/documentation.adoc[Working on documentation]
|
||||
*** xref:master@_:ROOT:development/ci.adoc[Jenkins CI environment]
|
||||
*** xref:master@_:ROOT:development/dependencies.adoc[Dependency management]
|
||||
*** xref:master@_:ROOT:development/release_process.adoc[Release process]
|
||||
|
||||
** xref:overview:faq/index.adoc[FAQ]
|
||||
|
||||
** xref:integrating:plugins/index.adoc[Plug-ins]
|
||||
|
||||
*** xref:master@_:ROOT:development/release_process.adoc[Release process]
|
||||
|
|
@ -41,7 +41,7 @@ clocks were used to reconcile concurrent updates to a key, Cassandra
|
|||
uses a simpler last-write-wins model where every mutation is timestamped
|
||||
(including deletes) and then the latest version of data is the "winning"
|
||||
value. Formally speaking, Cassandra uses a Last-Write-Wins Element-Set
|
||||
conflict-free replicated data type for each CQL row, or
|
||||
conflict-free replicated data type for each CQL row, or
|
||||
https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#LWW-Element-Set_(Last-Write-Wins-Element-Set)[LWW-Element-Set
|
||||
CRDT], to resolve conflicting mutations on replica sets.
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ clusters where you do not yet know the datacenter layout of the cluster.
|
|||
[[network-topology-strategy]]
|
||||
==== `NetworkTopologyStrategy`
|
||||
|
||||
`NetworkTopologyStrategy` requires a specified replication factor
|
||||
`NetworkTopologyStrategy` requires a specified replication factor
|
||||
for each datacenter in the cluster. Even if your cluster only uses a
|
||||
single datacenter, `NetworkTopologyStrategy` is recommended over
|
||||
`SimpleStrategy` to make it easier to add new physical or virtual
|
||||
|
|
@ -429,7 +429,6 @@ seed nodes, often one for each rack or datacenter. Seed nodes are often
|
|||
chosen using existing off-the-shelf service discovery mechanisms.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
Nodes do not have to agree on the seed nodes, and indeed once a cluster
|
||||
is bootstrapped, newly launched nodes can be configured to use any
|
||||
|
|
@ -462,7 +461,6 @@ will try to reach out and connect, and if it can open communication
|
|||
channels it will mark that node as available.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
`UP` and `DOWN` state are local node decisions and are not propagated with
|
||||
gossip. Heartbeat state is propagated with gossip, but nodes will not
|
||||
|
|
|
|||
|
|
@ -29,10 +29,9 @@ inherent risk of partition failure, one has to choose between
|
|||
consistency and availability and both cannot be guaranteed at the same
|
||||
time. CAP theorem is illustrated in Figure 1.
|
||||
|
||||
.CAP Theorem
|
||||
image::Figure_1_guarantees.jpg[image]
|
||||
|
||||
Figure 1. CAP Theorem
|
||||
|
||||
High availability is a priority in web-based applications and to this
|
||||
objective Cassandra chooses Availability and Partition Tolerance from
|
||||
the CAP guarantees, compromising on data Consistency to some extent.
|
||||
|
|
|
|||
|
|
@ -38,18 +38,18 @@ following design objectives:
|
|||
|
||||
== Features
|
||||
|
||||
Cassandra provides the Cassandra Query Language (xref:cql/ddl.adoc[CQL]), an SQL-like
|
||||
Cassandra provides the Cassandra Query Language (xref:cassandra:developing/cql/ddl.adoc[CQL]), an SQL-like
|
||||
language, to create and update database schema and access data. CQL
|
||||
allows users to organize data within a cluster of Cassandra nodes using:
|
||||
|
||||
* *Keyspace*: Defines how a dataset is replicated, per datacenter.
|
||||
* *Keyspace*: Defines how a dataset is replicated, per datacenter.
|
||||
Replication is the number of copies saved per cluster.
|
||||
Keyspaces contain tables.
|
||||
* *Table*: Defines the typed schema for a collection of partitions.
|
||||
Tables contain partitions, which contain rows, which contain columns.
|
||||
Cassandra tables can flexibly add new columns to tables with zero downtime.
|
||||
Cassandra tables can flexibly add new columns to tables with zero downtime.
|
||||
* *Partition*: Defines the mandatory part of the primary key all rows in
|
||||
Cassandra must have to identify the node in a cluster where the row is stored.
|
||||
Cassandra must have to identify the node in a cluster where the row is stored.
|
||||
All performant queries supply the partition key in the query.
|
||||
* *Row*: Contains a collection of columns identified by a unique primary
|
||||
key made up of the partition key and optionally additional clustering
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ granularity of archiving; 8 or 16 MiB is reasonable.
|
|||
`max_mutation_size` is a half the size of `commitlog_segment_size`.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
If `max_mutation_size` is set explicitly then
|
||||
`commitlog_segment_size` must be set to at least twice the size of
|
||||
|
|
@ -49,7 +48,6 @@ _Default Value:_ 10000ms
|
|||
_Default Value:_ batch
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
In the event of an unexpected shutdown, Cassandra can lose up
|
||||
to the sync period or more if the sync is delayed. If using "batch"
|
||||
|
|
@ -218,5 +216,5 @@ match the "ib" SSTable version
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/find_sstables.sh[]
|
||||
include::cassandra:example$BASH/find_sstables.sh[]
|
||||
----
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ This will increase the performance of bootstrapping a node and will also
|
|||
put less pressure on nodes serving the data. This does not affect if N <
|
||||
3 in each DC as then it streams data from only 2 nodes.
|
||||
|
||||
Stream Operation Types ^^^^^^^^^^^^^
|
||||
=== Stream Operation Types
|
||||
|
||||
It is important to know the type or purpose of a certain stream. Version
|
||||
4.0
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
== Cassandra Query Language (CQL) v3.4.3
|
||||
= Cassandra Query Language (CQL) v3.4.3
|
||||
|
||||
\{toc:maxLevel=3}
|
||||
|
||||
=== CQL Syntax
|
||||
== CQL Syntax
|
||||
|
||||
==== Preamble
|
||||
=== Preamble
|
||||
|
||||
This document describes the Cassandra Query Language (CQL) version 3.
|
||||
CQL v3 is not backward compatible with CQL v2 and differs from it in
|
||||
|
|
@ -19,7 +19,7 @@ definition than they have in SQL. But please note that as such, they do
|
|||
*not* refer to the concept of rows and columns found in the internal
|
||||
implementation of Cassandra and in the thrift and CQL v2 API.
|
||||
|
||||
==== Conventions
|
||||
=== Conventions
|
||||
|
||||
To aid in specifying the CQL syntax, we will use the following
|
||||
conventions in this document:
|
||||
|
|
@ -49,7 +49,7 @@ bc(sample). SELECT sample_usage FROM cql;
|
|||
shown in a `fixed-width font`.
|
||||
|
||||
[[identifiers]]
|
||||
==== Identifiers and keywords
|
||||
=== Identifiers and keywords
|
||||
|
||||
The CQL language uses _identifiers_ (or _names_) to identify tables,
|
||||
columns and other objects. An identifier is a token matching the regular
|
||||
|
|
@ -90,7 +90,7 @@ identifiers, it is strongly advised to avoid any name enclosed by
|
|||
squared brackets (like `"[applied]"`) and any name that looks like a
|
||||
function call (like `"f(x)"`).
|
||||
|
||||
==== Constants
|
||||
=== Constants
|
||||
|
||||
CQL defines the following kind of _constants_: strings, integers,
|
||||
floats, booleans, uuids and blobs:
|
||||
|
|
@ -122,17 +122,17 @@ CQL support. Terms are defined by:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/term.bnf[]
|
||||
include::cassandra:example$BNF/term.bnf[]
|
||||
----
|
||||
|
||||
A term is thus one of:
|
||||
|
||||
* A xref:cql/defintions.adoc#constants[constant]
|
||||
* A literal for either a xref:cql/types.adoc#collections[collection], a xref:cql/types.adoc#vectors[vector],
|
||||
a xref:cql/types.adoc#udts[user-defined type] or a xref:cql/types.adoc#tuples[tuple]
|
||||
* A xref:cql/functions.adoc#cql-functions[function] call, either a xref:cql/functions.adoc#scalar-native-functions[native function]
|
||||
or a xref:cql/functions.adoc#user-defined-scalar-functions[user-defined function]
|
||||
* An xref:cql/operators.adoc#arithmetic_operators[arithmetic operation] between terms
|
||||
* A xref:cassandra:developing/cql/defintions.adoc#constants[constant]
|
||||
* A literal for either a xref:cassandra:developing/cql/types.adoc#collections[collection], a xref:cassandra:developing/cql/types.adoc#vectors[vector],
|
||||
a xref:cassandra:developing/cql/types.adoc#udts[user-defined type] or a xref:cassandra:developing/cql/types.adoc#tuples[tuple]
|
||||
* A xref:cassandra:developing/cql/functions.adoc#cql-functions[function] call, either a xref:cassandra:developing/cql/functions.adoc#scalar-native-functions[native function]
|
||||
or a xref:cassandra:developing/cql/functions.adoc#user-defined-scalar-functions[user-defined function]
|
||||
* An xref:cassandra:developing/cql/operators.adoc#arithmetic_operators[arithmetic operation] between terms
|
||||
* A type hint
|
||||
* A bind marker, which denotes a variable to be bound at execution time.
|
||||
See the section on `prepared-statements` for details. A bind marker can
|
||||
|
|
@ -140,7 +140,7 @@ be either anonymous (`?`) or named (`:some_name`). The latter form
|
|||
provides a more convenient way to refer to the variable for binding it
|
||||
and should generally be preferred.
|
||||
|
||||
==== Comments
|
||||
=== Comments
|
||||
|
||||
A comment in CQL is a line beginning by either double dashes (`--`) or
|
||||
double slash (`//`).
|
||||
|
|
@ -154,7 +154,7 @@ bc(sample). +
|
|||
/* This is +
|
||||
a multi-line comment */
|
||||
|
||||
==== Statements
|
||||
=== Statements
|
||||
|
||||
CQL consists of statements. As in SQL, these statements can be divided
|
||||
in 3 categories:
|
||||
|
|
@ -245,7 +245,7 @@ $$double-dollar string can contain single ’ quotes$$ +
|
|||
p.
|
||||
|
||||
[[preparedStatement]]
|
||||
==== Prepared Statement
|
||||
=== Prepared Statement
|
||||
|
||||
CQL supports _prepared statements_. Prepared statement is an
|
||||
optimization that allows to parse a query only once but execute it
|
||||
|
|
@ -265,10 +265,10 @@ bind markers are used, the names for the query parameters will be
|
|||
`[limit]`, `[timestamp]`, and `[ttl]`, respectively.
|
||||
|
||||
[[dataDefinition]]
|
||||
=== Data Definition
|
||||
== Data Definition
|
||||
|
||||
[[createKeyspaceStmt]]
|
||||
==== CREATE KEYSPACE
|
||||
=== CREATE KEYSPACE
|
||||
|
||||
_Syntax:_
|
||||
|
||||
|
|
@ -326,7 +326,7 @@ unless the `IF NOT EXISTS` option is used. If it is used, the statement
|
|||
will be a no-op if the keyspace already exists.
|
||||
|
||||
[[useStmt]]
|
||||
==== USE
|
||||
=== USE
|
||||
|
||||
_Syntax:_
|
||||
|
||||
|
|
@ -343,7 +343,7 @@ selected keyspace, unless link:#statements[otherwise specified], until
|
|||
another USE statement is issued or the connection terminates.
|
||||
|
||||
[[alterKeyspaceStmt]]
|
||||
==== ALTER KEYSPACE
|
||||
=== ALTER KEYSPACE
|
||||
|
||||
_Syntax:_
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ keyspace. The supported `<properties>` are the same as for the
|
|||
link:#createKeyspaceStmt[`CREATE KEYSPACE`] statement.
|
||||
|
||||
[[dropKeyspaceStmt]]
|
||||
==== DROP KEYSPACE
|
||||
=== DROP KEYSPACE
|
||||
|
||||
_Syntax:_
|
||||
|
||||
|
|
@ -380,7 +380,7 @@ If the keyspace does not exists, the statement will return an error,
|
|||
unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
|
||||
[[createTableStmt]]
|
||||
==== CREATE TABLE
|
||||
=== CREATE TABLE
|
||||
|
||||
_Syntax:_
|
||||
|
||||
|
|
@ -431,7 +431,7 @@ unless the `IF NOT EXISTS` option is used. If it is used, the statement
|
|||
will be a no-op if the table already exists.
|
||||
|
||||
[[createTableName]]
|
||||
===== `<tablename>`
|
||||
==== `<tablename>`
|
||||
|
||||
Valid table names are the same as valid
|
||||
link:#createKeyspaceStmt[keyspace names] (up to 32 characters long
|
||||
|
|
@ -442,7 +442,7 @@ link:#statements[`<tablename>`] grammar), it is created in the specified
|
|||
keyspace (but does *not* change the current keyspace).
|
||||
|
||||
[[createTableColumn]]
|
||||
===== `<column-definition>`
|
||||
==== `<column-definition>`
|
||||
|
||||
A `CREATE TABLE` statement defines the columns that rows of the table
|
||||
can have. A _column_ is defined by its name (an identifier) and its type
|
||||
|
|
@ -474,7 +474,7 @@ PRIMARY KEY (k) +
|
|||
)
|
||||
|
||||
[[createTablepartitionClustering]]
|
||||
===== Partition key and clustering columns
|
||||
==== Partition key and clustering columns
|
||||
|
||||
In CQL, the order in which columns are defined for the `PRIMARY KEY`
|
||||
matters. The first column of the key is called the _partition key_. It
|
||||
|
|
@ -493,7 +493,7 @@ making the retrieval of rows in that clustering order particularly
|
|||
efficient (see `SELECT`).
|
||||
|
||||
[[createTableStatic]]
|
||||
===== `STATIC` columns
|
||||
==== `STATIC` columns
|
||||
|
||||
Some columns can be declared as `STATIC` in a table definition. A column
|
||||
that is static will be ``shared'' by all the rows belonging to the same
|
||||
|
|
@ -527,7 +527,7 @@ so every column is inherently static).
|
|||
* only non `PRIMARY KEY` columns can be static
|
||||
|
||||
[[createTableOptions]]
|
||||
===== `<option>`
|
||||
==== `<option>`
|
||||
|
||||
The `CREATE TABLE` statement supports a number of options that controls
|
||||
the configuration of a new table. These options can be specified after
|
||||
|
|
@ -582,7 +582,7 @@ link:#cachingOptions[below].
|
|||
|===
|
||||
|
||||
[[compactionOptions]]
|
||||
===== Compaction options
|
||||
==== Compaction options
|
||||
|
||||
The `compaction` property must at least define the `'class'` sub-option,
|
||||
that defines the compaction strategy class to use. The default supported
|
||||
|
|
@ -3051,7 +3051,7 @@ You can define, insert and update a vector with:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/vector.cql[]
|
||||
include::cassandra:example$CQL/vector.cql[]
|
||||
----
|
||||
|
||||
Note that it isn't possible to change the individual values of a vector, and it isn't possible to select individual
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
:tabs:
|
||||
|
||||
CQL stores data in _tables_, whose schema defines the layout of the
|
||||
data in the table. Tables are located in _keyspaces_.
|
||||
A keyspace defines options that apply to all the keyspace's tables.
|
||||
The xref:cql/ddl.adoc#replication-strategy[replication strategy]
|
||||
is an important keyspace option, as is the replication factor.
|
||||
data in the table. Tables are located in _keyspaces_.
|
||||
A keyspace defines options that apply to all the keyspace's tables.
|
||||
The xref:cassandra:developing/cql/ddl.adoc#replication-strategy[replication strategy]
|
||||
is an important keyspace option, as is the replication factor.
|
||||
A good general rule is one keyspace per application.
|
||||
It is common for a cluster to define only one keyspace for an active application.
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ grammar:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/ks_table.bnf[]
|
||||
include::cassandra:example$BNF/ks_table.bnf[]
|
||||
----
|
||||
|
||||
Both keyspace and table name should be comprised of only alphanumeric
|
||||
|
|
@ -33,13 +33,13 @@ double-quotes (`"myTable"` is different from `mytable`).
|
|||
Further, a table is always part of a keyspace and a table name can be
|
||||
provided fully-qualified by the keyspace it is part of. If is is not
|
||||
fully-qualified, the table is assumed to be in the _current_ keyspace
|
||||
(see xref:cql/ddl.adoc#use-statement[USE] statement).
|
||||
(see xref:cassandra:developing/cql/ddl.adoc#use-statement[USE] statement).
|
||||
|
||||
Further, the valid names for columns are defined as:
|
||||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/column.bnf[]
|
||||
include::cassandra:example$BNF/column.bnf[]
|
||||
----
|
||||
|
||||
We also define the notion of statement options for use in the following
|
||||
|
|
@ -47,7 +47,7 @@ section:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/options.bnf[]
|
||||
include::cassandra:example$BNF/options.bnf[]
|
||||
----
|
||||
|
||||
[[create-keyspace-statement]]
|
||||
|
|
@ -57,14 +57,14 @@ A keyspace is created with a `CREATE KEYSPACE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/create_ks.bnf[]
|
||||
include::cassandra:example$BNF/create_ks.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_ks.cql[]
|
||||
include::cassandra:example$CQL/create_ks.cql[]
|
||||
----
|
||||
|
||||
Attempting to create a keyspace that already exists will return an error
|
||||
|
|
@ -83,8 +83,8 @@ option at your own risk!).
|
|||
|===
|
||||
|
||||
The `replication` property is mandatory and must contain the `'class'` sub-option that defines the desired
|
||||
xref:cql/ddl.adoc#replication-strategy[replication strategy] class.
|
||||
The rest of the sub-options depend on which replication strategy is used.
|
||||
xref:cassandra:developing/cql/ddl.adoc#replication-strategy[replication strategy] class.
|
||||
The rest of the sub-options depend on which replication strategy is used.
|
||||
By default, Cassandra supports the following `'class'` values:
|
||||
|
||||
[[replication-strategy]]
|
||||
|
|
@ -123,7 +123,7 @@ replicas per datacenter, set a value of 3.
|
|||
When later altering keyspaces and changing the `replication_factor`,
|
||||
auto-expansion will only _add_ new datacenters for safety, it will not
|
||||
alter existing datacenters or remove any, even if they are no longer in
|
||||
the cluster. If you want to remove datacenters while setting the
|
||||
the cluster. If you want to remove datacenters while setting the
|
||||
`replication_factor`, explicitly zero out the datacenter you want to
|
||||
have zero replicas.
|
||||
|
||||
|
|
@ -132,36 +132,36 @@ An example of auto-expanding datacenters with two datacenters: `DC1` and
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/autoexpand_ks.cql[]
|
||||
include::cassandra:example$CQL/autoexpand_ks.cql[]
|
||||
----
|
||||
will result in:
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/autoexpand_ks.result[]
|
||||
include::cassandra:example$RESULTS/autoexpand_ks.result[]
|
||||
----
|
||||
|
||||
An example of auto-expanding and overriding a datacenter:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/autoexpand_ks_override.cql[]
|
||||
include::cassandra:example$CQL/autoexpand_ks_override.cql[]
|
||||
----
|
||||
will result in:
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/autoexpand_ks_override.result[]
|
||||
include::cassandra:example$RESULTS/autoexpand_ks_override.result[]
|
||||
----
|
||||
|
||||
An example that excludes a datacenter while using `replication_factor`:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/autoexpand_exclude_dc.cql[]
|
||||
include::cassandra:example$CQL/autoexpand_exclude_dc.cql[]
|
||||
----
|
||||
will result in:
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/autoexpand_exclude_dc.result[]
|
||||
include::cassandra:example$RESULTS/autoexpand_exclude_dc.result[]
|
||||
----
|
||||
|
||||
If xref:new/transientreplication.adoc[transient replication] has been enabled, transient replicas can be
|
||||
|
|
@ -174,26 +174,26 @@ transient, and 5 replicas in DC2, 2 of which are transient:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_ks_trans_repl.cql[]
|
||||
include::cassandra:example$CQL/create_ks_trans_repl.cql[]
|
||||
----
|
||||
|
||||
[[use-statement]]
|
||||
== USE
|
||||
|
||||
The `USE` statement changes the _current_ keyspace to the specified keyspace.
|
||||
The `USE` statement changes the _current_ keyspace to the specified keyspace.
|
||||
A number of objects in CQL are bound to a keyspace (tables, user-defined types, functions, etc.) and the
|
||||
current keyspace is the default keyspace used when those objects are
|
||||
referred to in a query without a fully-qualified name (without a prefixed keyspace name).
|
||||
referred to in a query without a fully-qualified name (without a prefixed keyspace name).
|
||||
A `USE` statement specifies the keyspace to use as an argument:
|
||||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/use_ks.bnf[]
|
||||
include::cassandra:example$BNF/use_ks.bnf[]
|
||||
----
|
||||
Using CQL:
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/use_ks.cql[]
|
||||
include::cassandra:example$CQL/use_ks.cql[]
|
||||
----
|
||||
|
||||
[[alter-keyspace-statement]]
|
||||
|
|
@ -203,17 +203,17 @@ An `ALTER KEYSPACE` statement modifies the options of a keyspace:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/alter_ks.bnf[]
|
||||
include::cassandra:example$BNF/alter_ks.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/alter_ks.cql[]
|
||||
include::cassandra:example$CQL/alter_ks.cql[]
|
||||
----
|
||||
If the keyspace does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
The supported options are the same as for xref:cql/ddl.adoc#create-keyspace-statement[creating a keyspace].
|
||||
The supported options are the same as for xref:cassandra:developing/cql/ddl.adoc#create-keyspace-statement[creating a keyspace].
|
||||
|
||||
[[drop-keyspace-statement]]
|
||||
== DROP KEYSPACE
|
||||
|
|
@ -222,14 +222,14 @@ Dropping a keyspace is done with the `DROP KEYSPACE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/drop_ks.bnf[]
|
||||
include::cassandra:example$BNF/drop_ks.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/drop_ks.cql[]
|
||||
include::cassandra:example$CQL/drop_ks.cql[]
|
||||
----
|
||||
|
||||
Dropping a keyspace results in the immediate, irreversible removal of
|
||||
|
|
@ -246,20 +246,20 @@ Creating a new table uses the `CREATE TABLE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/create_table.bnf[]
|
||||
include::cassandra:example$BNF/create_table.bnf[]
|
||||
----
|
||||
|
||||
For example, here are some CQL statements to create tables:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table.cql[]
|
||||
include::cassandra:example$CQL/create_table.cql[]
|
||||
----
|
||||
|
||||
A CQL table has a name and is composed of a set of _rows_.
|
||||
Creating a table amounts to defining which xref:cql/ddl.adoc#column-definition[columns] each rows will have,
|
||||
which of those columns comprise the xref:cql/ddl.adoc#primary-key[primary key], as well as defined
|
||||
xref:cql/ddl.adoc#create-table-options[options] for the table.
|
||||
A CQL table has a name and is composed of a set of _rows_.
|
||||
Creating a table amounts to defining which xref:cassandra:developing/cql/ddl.adoc#column-definition[columns] each rows will have,
|
||||
which of those columns comprise the xref:cassandra:developing/cql/ddl.adoc#primary-key[primary key], as well as defined
|
||||
xref:cassandra:developing/cql/ddl.adoc#create-table-options[options] for the table.
|
||||
|
||||
Attempting to create an already existing table will return an error
|
||||
unless the `IF NOT EXISTS` directive is used. If it is used, the
|
||||
|
|
@ -268,35 +268,35 @@ statement will be a no-op if the table already exists.
|
|||
[[column-definition]]
|
||||
=== Column definitions
|
||||
|
||||
Every row in a CQL table will have the predefined columns defined at table creation.
|
||||
Columns can be added later using an xref:cql/ddl.adoc#alter-table-statement[alter statement].
|
||||
Every row in a CQL table will have the predefined columns defined at table creation.
|
||||
Columns can be added later using an xref:cassandra:developing/cql/ddl.adoc#alter-table-statement[alter statement].
|
||||
|
||||
A `column_definition` is comprised of the name of the column and its xref:cql/ddl.adoc#data-type[type],
|
||||
A `column_definition` is comprised of the name of the column and its xref:cassandra:developing/cql/ddl.adoc#data-type[type],
|
||||
restricting the values that are accepted for that column. Additionally, a column definition can have the
|
||||
following modifiers:
|
||||
|
||||
* `STATIC`: declares the column as a xref:cql/ddl.adoc#static-column[static column]
|
||||
* `PRIMARY KEY`: declares the column as the sole component of the xref:cql/ddl.adoc#primary-key[primary key] of the table
|
||||
* `STATIC`: declares the column as a xref:cassandra:developing/cql/ddl.adoc#static-column[static column]
|
||||
* `PRIMARY KEY`: declares the column as the sole component of the xref:cassandra:developing/cql/ddl.adoc#primary-key[primary key] of the table
|
||||
|
||||
[[static-column]]
|
||||
==== Static columns
|
||||
|
||||
Some columns can be declared as `STATIC` in a table definition. A column
|
||||
that is static will be “shared” by all the rows belonging to the same
|
||||
partition (having the same xref:cql/ddl.adoc#partition-key[partition key].
|
||||
partition (having the same xref:cassandra:developing/cql/ddl.adoc#partition-key[partition key].
|
||||
|
||||
For example:
|
||||
|
||||
[{tabs}]
|
||||
====
|
||||
Code::
|
||||
+
|
||||
--
|
||||
[tabs]
|
||||
====
|
||||
Code::
|
||||
+
|
||||
--
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_static_column.cql[]
|
||||
include::example$CQL/insert_static_data.cql[]
|
||||
include::example$CQL/select_static_data.cql[]
|
||||
include::cassandra:example$CQL/create_static_column.cql[]
|
||||
include::cassandra:example$CQL/insert_static_data.cql[]
|
||||
include::cassandra:example$CQL/select_static_data.cql[]
|
||||
----
|
||||
--
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ Results::
|
|||
--
|
||||
[source,cql]
|
||||
----
|
||||
include::example$RESULTS/select_static_data.result[]
|
||||
include::cassandra:example$RESULTS/select_static_data.result[]
|
||||
----
|
||||
--
|
||||
====
|
||||
|
|
@ -317,7 +317,7 @@ value for `s`.
|
|||
|
||||
The use of static columns has the following restrictions:
|
||||
|
||||
* A table without clustering columns cannot have static columns.
|
||||
* A table without clustering columns cannot have static columns.
|
||||
In a table without clustering columns, every partition has only one row, and
|
||||
so every column is inherently static)
|
||||
* Only non-primary key columns can be static.
|
||||
|
|
@ -326,27 +326,27 @@ so every column is inherently static)
|
|||
=== The Primary key
|
||||
|
||||
Within a table, a row is uniquely identified by its `PRIMARY KEY`, and
|
||||
hence all tables *must* define a single PRIMARY KEY.
|
||||
A `PRIMARY KEY` is composed of one or more of the defined columns in the table.
|
||||
Syntactically, the primary key is defined with the phrase `PRIMARY KEY`
|
||||
hence all tables *must* define a single PRIMARY KEY.
|
||||
A `PRIMARY KEY` is composed of one or more of the defined columns in the table.
|
||||
Syntactically, the primary key is defined with the phrase `PRIMARY KEY`
|
||||
followed by a comma-separated list of the column names within parenthesis.
|
||||
If the primary key has only one column, you can alternatively add the `PRIMARY KEY` phrase to
|
||||
that column in the table definition.
|
||||
The order of the columns in the primary key definition defines the partition key and
|
||||
that column in the table definition.
|
||||
The order of the columns in the primary key definition defines the partition key and
|
||||
clustering columns.
|
||||
|
||||
A CQL primary key is composed of two parts:
|
||||
|
||||
xref:cql/ddl.adoc#partition-key[partition key]::
|
||||
* It is the first component of the primary key definition.
|
||||
It can be a single column or, using an additional set of parenthesis, can be multiple columns.
|
||||
xref:cassandra:developing/cql/ddl.adoc#partition-key[partition key]::
|
||||
* It is the first component of the primary key definition.
|
||||
It can be a single column or, using an additional set of parenthesis, can be multiple columns.
|
||||
A table must have at least one partition key, the smallest possible table definition is:
|
||||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table_single_pk.cql[]
|
||||
include::cassandra:example$CQL/create_table_single_pk.cql[]
|
||||
----
|
||||
xref:cql/ddl.adoc#clustering-columns[clustering columns]::
|
||||
xref:cassandra:developing/cql/ddl.adoc#clustering-columns[clustering columns]::
|
||||
* The columns are the columns that follow the partition key in the primary key definition.
|
||||
The order of those columns define the _clustering order_.
|
||||
|
||||
|
|
@ -358,9 +358,9 @@ Some examples of primary key definition are:
|
|||
|
||||
[IMPORTANT]
|
||||
====
|
||||
The primary key uniquely identifies a row in the table, as described above.
|
||||
A consequence of this uniqueness is that if another row is inserted using the same primary key,
|
||||
then an `UPSERT` occurs and an existing row with the same primary key is replaced.
|
||||
The primary key uniquely identifies a row in the table, as described above.
|
||||
A consequence of this uniqueness is that if another row is inserted using the same primary key,
|
||||
then an `UPSERT` occurs and an existing row with the same primary key is replaced.
|
||||
Columns that are not part of the primary key cannot define uniqueness.
|
||||
====
|
||||
|
||||
|
|
@ -368,24 +368,24 @@ Columns that are not part of the primary key cannot define uniqueness.
|
|||
==== Partition key
|
||||
|
||||
Within a table, CQL defines the notion of a _partition_ that defines the location of data within a Cassandra cluster.
|
||||
A partition is the set of rows that share the same value for their partition key.
|
||||
A partition is the set of rows that share the same value for their partition key.
|
||||
|
||||
Note that if the partition key is composed of multiple columns, then rows belong to the same partition
|
||||
when they have the same values for all those partition key columns.
|
||||
Note that if the partition key is composed of multiple columns, then rows belong to the same partition
|
||||
when they have the same values for all those partition key columns.
|
||||
A hash is computed from the partition key columns and that hash value defines the partition location.
|
||||
So, for instance, given the following table definition and content:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table_compound_pk.cql[]
|
||||
include::example$CQL/insert_table_compound_pk.cql[]
|
||||
include::example$CQL/select_table_compound_pk.cql[]
|
||||
include::cassandra:example$CQL/create_table_compound_pk.cql[]
|
||||
include::cassandra:example$CQL/insert_table_compound_pk.cql[]
|
||||
include::cassandra:example$CQL/select_table_compound_pk.cql[]
|
||||
----
|
||||
|
||||
will result in
|
||||
[source,cql]
|
||||
----
|
||||
include::example$RESULTS/select_table_compound_pk.result[]
|
||||
include::cassandra:example$RESULTS/select_table_compound_pk.result[]
|
||||
----
|
||||
<1> Rows 1 and 2 are in the same partition, because both columns `a` and `b` are zero.
|
||||
<2> Rows 3 and 4 are in the same partition, but a different one, because column `a` is zero and column `b` is 1 in both rows.
|
||||
|
|
@ -397,23 +397,23 @@ because the partition key, compound or otherwise, identifies a single location.
|
|||
|
||||
The most important property of partition is that all the rows belonging
|
||||
to the same partition are guaranteed to be stored on the same set of
|
||||
replica nodes.
|
||||
In other words, the partition key of a table defines which rows will be localized on the same
|
||||
node in the cluster.
|
||||
replica nodes.
|
||||
In other words, the partition key of a table defines which rows will be localized on the same
|
||||
node in the cluster.
|
||||
The localization of data is important to the efficient retrieval of data, requiring the Cassandra coordinator
|
||||
to contact as few nodes as possible.
|
||||
However, there is a flip-side to this guarantee, and all rows sharing a partition key will be stored on the same
|
||||
However, there is a flip-side to this guarantee, and all rows sharing a partition key will be stored on the same
|
||||
node, creating a hotspot for both reading and writing.
|
||||
While selecting a primary key that groups table rows assists batch updates and can ensure that the updates are
|
||||
While selecting a primary key that groups table rows assists batch updates and can ensure that the updates are
|
||||
_atomic_ and done in _isolation_, the partitions must be sized "just right, not too big nor too small".
|
||||
|
||||
Data modeling that considers the querying patterns and assigns primary keys based on the queries will have the lowest
|
||||
Data modeling that considers the querying patterns and assigns primary keys based on the queries will have the lowest
|
||||
latency in fetching data.
|
||||
|
||||
[[clustering-columns]]
|
||||
==== Clustering columns
|
||||
|
||||
The clustering columns of a table define the clustering order for the partition of that table.
|
||||
The clustering columns of a table define the clustering order for the partition of that table.
|
||||
For a given `partition`, all rows are ordered by that clustering order. Clustering columns also add uniqueness to
|
||||
a row in a table.
|
||||
|
||||
|
|
@ -421,34 +421,34 @@ For instance, given:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table_clustercolumn.cql[]
|
||||
include::example$CQL/insert_table_clustercolumn.cql[]
|
||||
include::example$CQL/select_table_clustercolumn.cql[]
|
||||
include::cassandra:example$CQL/create_table_clustercolumn.cql[]
|
||||
include::cassandra:example$CQL/insert_table_clustercolumn.cql[]
|
||||
include::cassandra:example$CQL/select_table_clustercolumn.cql[]
|
||||
----
|
||||
|
||||
will result in
|
||||
[source,cql]
|
||||
----
|
||||
include::example$RESULTS/select_table_clustercolumn.result[]
|
||||
include::cassandra:example$RESULTS/select_table_clustercolumn.result[]
|
||||
----
|
||||
<1> Row 1 is in one partition, and Rows 2-5 are in a different one. The display order is also different.
|
||||
|
||||
Looking more closely at the four rows in the same partition, the `b` clustering column defines the order in which those rows
|
||||
are displayed.
|
||||
Whereas the partition key of the table groups rows on the same node, the clustering columns control
|
||||
how those rows are stored on the node.
|
||||
Looking more closely at the four rows in the same partition, the `b` clustering column defines the order in which those rows
|
||||
are displayed.
|
||||
Whereas the partition key of the table groups rows on the same node, the clustering columns control
|
||||
how those rows are stored on the node.
|
||||
|
||||
That sorting allows the very efficient retrieval of a range of rows within a partition:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/select_range.cql[]
|
||||
include::cassandra:example$CQL/select_range.cql[]
|
||||
----
|
||||
|
||||
will result in
|
||||
[source,cql]
|
||||
----
|
||||
include::example$RESULTS/select_range.result[]
|
||||
include::cassandra:example$RESULTS/select_range.result[]
|
||||
----
|
||||
|
||||
[[create-table-options]]
|
||||
|
|
@ -463,27 +463,27 @@ One important option that cannot be changed after creation, `CLUSTERING ORDER BY
|
|||
[[clustering-order]]
|
||||
==== Clustering order
|
||||
|
||||
The clustering order of a table is defined by the clustering columns.
|
||||
By default, the clustering order is ascending for the clustering column's data types.
|
||||
For example, integers order from 1, 2, ... n, while text orders from A to Z.
|
||||
The clustering order of a table is defined by the clustering columns.
|
||||
By default, the clustering order is ascending for the clustering column's data types.
|
||||
For example, integers order from 1, 2, ... n, while text orders from A to Z.
|
||||
|
||||
The `CLUSTERING ORDER BY` table option uses a comma-separated list of the
|
||||
clustering columns, each set for either `ASC` (for _ascending_ order) or `DESC` (for _descending order).
|
||||
The default is ascending for all clustering columns if the `CLUSTERING ORDER BY` option is not set.
|
||||
The default is ascending for all clustering columns if the `CLUSTERING ORDER BY` option is not set.
|
||||
|
||||
This option is basically a hint for the storage engine that changes the order in which it stores the row.
|
||||
Beware of the consequences of setting this option:
|
||||
|
||||
* It changes the default ascending order of results when queried with a `SELECT` statement with no `ORDER BY` clause.
|
||||
|
||||
* It limits how the `ORDER BY` clause is used in `SELECT` statements on that table.
|
||||
* It limits how the `ORDER BY` clause is used in `SELECT` statements on that table.
|
||||
Results can only be ordered with either the original clustering order or the reverse clustering order.
|
||||
Suppose you create a table with two clustering columns `a` and `b`, defined `WITH CLUSTERING ORDER BY (a DESC, b ASC)`.
|
||||
Queries on the table can use `ORDER BY (a DESC, b ASC)` or `ORDER BY (a ASC, b DESC)`.
|
||||
Queries on the table can use `ORDER BY (a DESC, b ASC)` or `ORDER BY (a ASC, b DESC)`.
|
||||
Mixed order, such as `ORDER BY (a ASC, b ASC)` or `ORDER BY (a DESC, b DESC)` will not return expected order.
|
||||
|
||||
* It has a performance impact on queries. Queries in reverse clustering order are slower than the default ascending order.
|
||||
If you plan to query mostly in descending order, declare the clustering order in the table schema using `WITH CLUSTERING ORDER BY ()`.
|
||||
If you plan to query mostly in descending order, declare the clustering order in the table schema using `WITH CLUSTERING ORDER BY ()`.
|
||||
This optimization is common for time series, to retrieve the data from newest to oldest.
|
||||
|
||||
[[create-table-general-options]]
|
||||
|
|
@ -496,7 +496,7 @@ A table supports the following options:
|
|||
|option | kind | default | description
|
||||
|
||||
| `comment` | _simple_ | none | A free-form, human-readable comment
|
||||
| xref:cql/ddl.adoc#spec_retry[`speculative_retry`] | _simple_ | 99PERCENTILE | Speculative retry options
|
||||
| xref:cassandra:developing/cql/ddl.adoc#spec_retry[`speculative_retry`] | _simple_ | 99PERCENTILE | Speculative retry options
|
||||
| `cdc` |_boolean_ |false |Create a Change Data Capture (CDC) log on the table
|
||||
| `additional_write_policy` |_simple_ |99PERCENTILE | Same as `speculative_retry`
|
||||
| `gc_grace_seconds` |_simple_ |864000 |Time to wait before garbage collecting tombstones (deletion markers)
|
||||
|
|
@ -505,8 +505,8 @@ false positive of the sstable bloom filters. Said bloom filters will be
|
|||
sized to provide the provided probability, thus lowering this value
|
||||
impacts the size of bloom filters in-memory and on-disk.
|
||||
| `default_time_to_live` |_simple_ |0 |Default expiration time (“TTL”) in seconds for a table
|
||||
| `compaction` |_map_ |_see below_ | xref:operating/compaction/index.adoc#cql-compaction-options[Compaction options]
|
||||
| `compression` |_map_ |_see below_ | xref:operating/compression/index.adoc#cql-compression-options[Compression options]
|
||||
| `compaction` |_map_ |_see below_ | xref:cassandra:managing/operating/compaction/index.adoc#cql-compaction-options[Compaction options]
|
||||
| `compression` |_map_ |_see below_ | xref:cassandra:managing/operating/compression/index.adoc#cql-compression-options[Compression options]
|
||||
| `caching` |_map_ |_see below_ |Caching options
|
||||
| `memtable_flush_period_in_ms` |_simple_ |0 |Time (in ms) before Cassandra flushes memtables to disk
|
||||
| `read_repair` |_simple_ |BLOCKING |Sets read repair behavior (see below)
|
||||
|
|
@ -519,7 +519,7 @@ By default, Cassandra read coordinators only query as many replicas as
|
|||
necessary to satisfy consistency levels: one for consistency level
|
||||
`ONE`, a quorum for `QUORUM`, and so on. `speculative_retry` determines
|
||||
when coordinators may query additional replicas, a useful action when
|
||||
replicas are slow or unresponsive. Speculative retries reduce the latency.
|
||||
replicas are slow or unresponsive. Speculative retries reduce the latency.
|
||||
The speculative_retry option configures rapid read protection, where a coordinator sends more
|
||||
requests than needed to satisfy the consistency level.
|
||||
|
||||
|
|
@ -540,20 +540,20 @@ An example of setting speculative retry sets a custom value:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/alter_table_spec_retry.cql[]
|
||||
include::cassandra:example$CQL/alter_table_spec_retry.cql[]
|
||||
----
|
||||
|
||||
This example uses a percentile for the setting:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/alter_table_spec_retry_percent.cql[]
|
||||
include::cassandra:example$CQL/alter_table_spec_retry_percent.cql[]
|
||||
----
|
||||
|
||||
A percentile setting can backfire. If a single host becomes unavailable, it can
|
||||
force up the percentiles. A value of `p99` will not speculate as intended because the
|
||||
value at the specified percentile has increased too much. If the consistency level is set to `ALL`, all
|
||||
replicas are queried regardless of the speculative retry setting.
|
||||
force up the percentiles. A value of `p99` will not speculate as intended because the
|
||||
value at the specified percentile has increased too much. If the consistency level is set to `ALL`, all
|
||||
replicas are queried regardless of the speculative retry setting.
|
||||
|
||||
Cassandra 4.0 supports case-insensitivity for speculative retry values (https://issues.apache.org/jira/browse/CASSANDRA-14293[CASSANDRA-14293]). For example, assigning the value as `none`, `None`, or `NONE` has the same effect.
|
||||
|
||||
|
|
@ -576,19 +576,19 @@ lower at the time of calculation. Parameters are `XPERCENTILE`, `XP`, or
|
|||
|
||||
| `MAX(XPERCENTILE,YMS)` `ALWAYS` `NEVER` | MAX(90.5P,25ms) | A hybrid policy that uses either the specified
|
||||
percentile or fixed milliseconds depending on which value is higher at
|
||||
the time of calculation.
|
||||
the time of calculation.
|
||||
|===
|
||||
|
||||
Cassandra 4.0 adds support for hybrid `MIN()` and `MAX()` speculative retry policies, with a mix and match of either `MIN(), MAX()`, `MIN(), MIN()`, or `MAX(), MAX()` (https://issues.apache.org/jira/browse/CASSANDRA-14293[CASSANDRA-14293]).
|
||||
The hybrid mode will still speculate if the normal `p99` for the table is < 50ms, the minimum value.
|
||||
But if the `p99` level goes higher than the maximum value, then that value can be used.
|
||||
But if the `p99` level goes higher than the maximum value, then that value can be used.
|
||||
In a hybrid value, one value must be a fixed time (ms) value and the other a percentile value.
|
||||
|
||||
To illustrate variations, the following examples are all valid:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/spec_retry_values.cql[]
|
||||
include::cassandra:example$CQL/spec_retry_values.cql[]
|
||||
----
|
||||
|
||||
The `additional_write_policy` setting specifies the threshold at which a cheap
|
||||
|
|
@ -598,16 +598,16 @@ quorum write will be upgraded to include transient replicas.
|
|||
===== Compaction options
|
||||
|
||||
The `compaction` options must minimally define the `'class'` sub-option,
|
||||
to specify the compaction strategy class to use.
|
||||
The supported classes are:
|
||||
to specify the compaction strategy class to use.
|
||||
The supported classes are:
|
||||
|
||||
* `'SizeTieredCompactionStrategy'`, xref:operating/compaction/stcs.adoc#stcs[STCS] (Default)
|
||||
* `'LeveledCompactionStrategy'`, xref:operating/compaction/lcs.adoc#lcs[LCS]
|
||||
* `'TimeWindowCompactionStrategy'`, xref:operating/compaction/twcs.adoc#twcs[TWCS]
|
||||
* `'SizeTieredCompactionStrategy'`, xref:cassandra:managing/operating/compaction/stcs.adoc#stcs[STCS] (Default)
|
||||
* `'LeveledCompactionStrategy'`, xref:cassandra:managing/operating/compaction/lcs.adoc#lcs[LCS]
|
||||
* `'TimeWindowCompactionStrategy'`, xref:cassandra:managing/operating/compaction/twcs.adoc#twcs[TWCS]
|
||||
|
||||
If a custom strategies is required, specify the full class name as a xref:cql/definitions.adoc#constants[string constant].
|
||||
If a custom strategies is required, specify the full class name as a xref:cassandra:developing/cql/definitions.adoc#constants[string constant].
|
||||
|
||||
All default strategies support a number of xref:operating/compaction/index.adoc#compaction-options[common options], as well as options specific to the strategy chosen. See the section corresponding to your strategy for details: xref:operating/compaction/stcs.adoc#stcs_options[STCS], xref:operating/compaction/lcs.adoc#lcs_options[LCS], xref:operating/compaction/twcs.adoc#twcs_options[TWCS].
|
||||
All default strategies support a number of xref:cassandra:managing/operating/compaction/index.adoc#compaction-options[common options], as well as options specific to the strategy chosen. See the section corresponding to your strategy for details: xref:cassandra:managing/operating/compaction/stcs.adoc#stcs_options[STCS], xref:cassandra:managing/operating/compaction/lcs.adoc#lcs_options[LCS], xref:cassandra:managing/operating/compaction/twcs.adoc#twcs_options[TWCS].
|
||||
|
||||
[[cql-compression-options]]
|
||||
===== Compression options
|
||||
|
|
@ -621,20 +621,20 @@ sub-options are available:
|
|||
|===
|
||||
|Option |Default |Description
|
||||
| `class` | LZ4Compressor | The compression algorithm to use. Default compressor are: LZ4Compressor,
|
||||
SnappyCompressor, DeflateCompressor and ZstdCompressor.
|
||||
Use `'enabled' : false` to disable compression.
|
||||
Custom compressor can be provided by specifying the full class name as a xref:cql/definitions.adoc#constants[string constant].
|
||||
SnappyCompressor, DeflateCompressor and ZstdCompressor.
|
||||
Use `'enabled' : false` to disable compression.
|
||||
Custom compressor can be provided by specifying the full class name as a xref:cassandra:developing/cql/definitions.adoc#constants[string constant].
|
||||
|
||||
| `enabled` | true | Enable/disable sstable compression.
|
||||
| `enabled` | true | Enable/disable sstable compression.
|
||||
If the `enabled` option is set to `false`, no other options must be specified.
|
||||
|
||||
| `chunk_length_in_kb` | 64 | On disk SSTables are compressed by block (to allow random reads).
|
||||
This option defines the size (in KB) of said block. See xref:cql/ddl.adoc#chunk_note[note] for further information.
|
||||
| `chunk_length_in_kb` | 64 | On disk SSTables are compressed by block (to allow random reads).
|
||||
This option defines the size (in KB) of said block. See xref:cassandra:developing/cql/ddl.adoc#chunk_note[note] for further information.
|
||||
|
||||
| `crc_check_chance` | 1.0 | Determines how likely Cassandra is to verify the checksum on each
|
||||
compression chunk during reads.
|
||||
|
||||
| `compression_level` | 3 | Compression level. Only applicable for `ZstdCompressor`.
|
||||
| `compression_level` | 3 | Compression level. Only applicable for `ZstdCompressor`.
|
||||
Accepts values between `-131072` and `22`.
|
||||
|===
|
||||
|
||||
|
|
@ -642,9 +642,9 @@ Accepts values between `-131072` and `22`.
|
|||
[NOTE]
|
||||
====
|
||||
Bigger values may improve the compression rate, but will increase the minimum size of data to be read from
|
||||
disk for a read.
|
||||
The default value is an optimal value for compressing tables.
|
||||
Chunk length must be a power of 2 when computing the chunk number from an uncompressed file offset.
|
||||
disk for a read.
|
||||
The default value is an optimal value for compressing tables.
|
||||
Chunk length must be a power of 2 when computing the chunk number from an uncompressed file offset.
|
||||
Block size may be adjusted based on read/write access patterns such as:
|
||||
|
||||
* How much data is typically requested at once
|
||||
|
|
@ -655,15 +655,15 @@ For instance, to create a table with LZ4Compressor and a `chunk_length_in_kb` of
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/chunk_length.cql[]
|
||||
include::cassandra:example$CQL/chunk_length.cql[]
|
||||
----
|
||||
|
||||
[[cql-caching-options]]
|
||||
===== Caching options
|
||||
|
||||
Caching optimizes the use of cache memory of a table. The cached data is
|
||||
weighed by size and access frequency.
|
||||
The `caching` options can configure both the `key cache` and the `row cache` for the table.
|
||||
weighed by size and access frequency.
|
||||
The `caching` options can configure both the `key cache` and the `row cache` for the table.
|
||||
The following sub-options are available:
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|
|
@ -671,8 +671,8 @@ The following sub-options are available:
|
|||
|Option |Default |Description
|
||||
| `keys` | ALL | Whether to cache keys (key cache) for this table. Valid values are: `ALL` and `NONE`.
|
||||
|
||||
| `rows_per_partition` | NONE | The amount of rows to cache per partition (row cache).
|
||||
If an integer `n` is specified, the first `n` queried rows of a partition will be cached.
|
||||
| `rows_per_partition` | NONE | The amount of rows to cache per partition (row cache).
|
||||
If an integer `n` is specified, the first `n` queried rows of a partition will be cached.
|
||||
Valid values are: `ALL`, to cache all rows of a queried partition, or `NONE` to disable row caching.
|
||||
|===
|
||||
|
||||
|
|
@ -680,13 +680,13 @@ For instance, to create a table with both a key cache and 10 rows cached per par
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/caching_option.cql[]
|
||||
include::cassandra:example$CQL/caching_option.cql[]
|
||||
----
|
||||
|
||||
[[read-repair-options]]
|
||||
===== Read Repair options
|
||||
|
||||
The `read_repair` options configure the read repair behavior, tuning for various performance and consistency behaviors.
|
||||
The `read_repair` options configure the read repair behavior, tuning for various performance and consistency behaviors.
|
||||
|
||||
The values are:
|
||||
[cols=",,",options="header",]
|
||||
|
|
@ -726,7 +726,7 @@ Altering an existing table uses the `ALTER TABLE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/alter_table.bnf[]
|
||||
include::cassandra:example$BNF/alter_table.bnf[]
|
||||
----
|
||||
If the table does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
|
||||
|
|
@ -734,20 +734,20 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/alter_table_add_column.cql[]
|
||||
include::example$CQL/alter_table_with_comment.cql[]
|
||||
include::cassandra:example$CQL/alter_table_add_column.cql[]
|
||||
include::cassandra:example$CQL/alter_table_with_comment.cql[]
|
||||
----
|
||||
|
||||
The `ALTER TABLE` statement can:
|
||||
|
||||
* `ADD` a new column to a table. The primary key of a table cannot ever be altered.
|
||||
A new column, thus, cannot be part of the primary key.
|
||||
A new column, thus, cannot be part of the primary key.
|
||||
Adding a column is a constant-time operation based on the amount of data in the table.
|
||||
If the new column already exists, the statement will return an error, unless `IF NOT EXISTS` is used in which case the operation is a no-op.
|
||||
* `DROP` a column from a table. This command drops both the column and all
|
||||
its content. Be aware that, while the column becomes immediately
|
||||
unavailable, its content are removed lazily during compaction. Because of this lazy removal,
|
||||
the command is a constant-time operation based on the amount of data in the table.
|
||||
the command is a constant-time operation based on the amount of data in the table.
|
||||
Also, it is important to know that once a column is dropped, a column with the same name can be re-added,
|
||||
unless the dropped column was a non-frozen column like a collection.
|
||||
If the dropped column does not already exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
|
|
@ -768,7 +768,7 @@ Furthermore, renaming a column to another name which already exists isn't allowe
|
|||
It's important to keep in mind that renamed columns shouldn't have dependent seconday indexes.
|
||||
If the renamed column does not already exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
|
||||
* Use `WITH` to change a table option. The xref:CQL/ddl.adoc#create-table-options[supported options]
|
||||
* Use `WITH` to change a table option. The xref:cassandra:developing/cql/ddl.adoc#create-table-options[supported options]
|
||||
are the same as those used when creating a table, with the exception of `CLUSTERING ORDER`.
|
||||
However, setting any `compaction` sub-options will erase *ALL* previous `compaction` options, so you need to re-specify
|
||||
all the sub-options you wish to keep. The same is true for `compression` sub-options.
|
||||
|
|
@ -780,7 +780,7 @@ Dropping a table uses the `DROP TABLE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/drop_table.bnf[]
|
||||
include::cassandra:example$BNF/drop_table.bnf[]
|
||||
----
|
||||
|
||||
Dropping a table results in the immediate, irreversible removal of the
|
||||
|
|
@ -796,11 +796,11 @@ A table can be truncated using the `TRUNCATE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/truncate_table.bnf[]
|
||||
include::cassandra:example$BNF/truncate_table.bnf[]
|
||||
----
|
||||
|
||||
`TRUNCATE TABLE foo` is the preferred syntax for consistency with other DDL
|
||||
statements.
|
||||
statements.
|
||||
However, tables are the only object that can be truncated currently, and the `TABLE` keyword can be omitted.
|
||||
|
||||
Truncating a table permanently removes all existing data from the table, but without removing the table itself.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ expression `[a-zA-Z][a-zA-Z0-9_]*`.
|
|||
|
||||
A number of such identifiers, like `SELECT` or `WITH`, are _keywords_.
|
||||
They have a fixed meaning for the language and most are reserved. The
|
||||
list of those keywords can be found in xref:cql/appendices.adoc#appendix-A[Appendix A].
|
||||
list of those keywords can be found in xref:cassandra:developing/cql/appendices.adoc#appendix-A[Appendix A].
|
||||
|
||||
Identifiers and (unquoted) keywords are case insensitive. Thus `SELECT`
|
||||
is the same than `select` or `sElEcT`, and `myId` is the same than
|
||||
|
|
@ -56,7 +56,6 @@ Inside a quoted identifier, the double-quote character can be repeated
|
|||
to escape it, so `"foo "" bar"` is a valid identifier.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
The _quoted identifier_ can declare columns with arbitrary names, and
|
||||
these can sometime clash with specific names used by the server. For
|
||||
|
|
@ -73,7 +72,7 @@ More formally, we have:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/identifier.bnf[]
|
||||
include::cassandra:example$BNF/identifier.bnf[]
|
||||
----
|
||||
|
||||
[[constants]]
|
||||
|
|
@ -83,7 +82,7 @@ CQL defines the following _constants_:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/constant.bnf[]
|
||||
include::cassandra:example$BNF/constant.bnf[]
|
||||
----
|
||||
|
||||
In other words:
|
||||
|
|
@ -95,7 +94,7 @@ single-quote(`'`). A single-quote can be included by repeating it, e.g.
|
|||
defined by enclosing the arbitrary sequence of characters by two dollar
|
||||
characters, in which case single-quote can be used without escaping
|
||||
(`$$It's raining today$$`). That latter form is often used when defining
|
||||
xref:cql/functions.adoc#udfs[user-defined functions] to avoid having to escape single-quote
|
||||
xref:cassandra:developing/cql/functions.adoc#udfs[user-defined functions] to avoid having to escape single-quote
|
||||
characters in function body (as they are more likely to occur than
|
||||
`$$`).
|
||||
* Integer, float and boolean constant are defined as expected. Note
|
||||
|
|
@ -106,7 +105,7 @@ constants.
|
|||
* The content for blobs is provided in hexadecimal and prefixed by `0x`.
|
||||
* The special `NULL` constant denotes the absence of value.
|
||||
|
||||
For how these constants are typed, see the xref:cql/types.adoc[Data types] section.
|
||||
For how these constants are typed, see the xref:cassandra:developing/cql/types.adoc[Data types] section.
|
||||
|
||||
== Terms
|
||||
|
||||
|
|
@ -115,17 +114,17 @@ CQL support. Terms are defined by:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/term.bnf[]
|
||||
include::cassandra:example$BNF/term.bnf[]
|
||||
----
|
||||
|
||||
A term is thus one of:
|
||||
|
||||
* A xref:cql/defintions.adoc#constants[constant]
|
||||
* A literal for either a xref:cql/types.adoc#collections[collection], a xref:cql/types.adoc#vectors[vector],
|
||||
a xref:cql/types.adoc#udts[user-defined type] or a xref:cql/types.adoc#tuples[tuple]
|
||||
* A xref:cql/functions.adoc#cql-functions[function] call, either a xref:cql/functions.adoc#scalar-native-functions[native function]
|
||||
or a xref:cql/functions.adoc#user-defined-scalar-functions[user-defined function]
|
||||
* An xref:cql/operators.adoc#arithmetic_operators[arithmetic operation] between terms
|
||||
* A xref:cassandra:developing/cql/defintions.adoc#constants[constant]
|
||||
* A literal for either a xref:cassandra:developing/cql/types.adoc#collections[collection], a xref:cassandra:developing/cql/types.adoc#vectors[vector],
|
||||
a xref:cassandra:developing/cql/types.adoc#udts[user-defined type] or a xref:cassandra:developing/cql/types.adoc#tuples[tuple]
|
||||
* A xref:cassandra:developing/cql/functions.adoc#cql-functions[function] call, either a xref:cassandra:developing/cql/functions.adoc#scalar-native-functions[native function]
|
||||
or a xref:cassandra:developing/cql/functions.adoc#user-defined-scalar-functions[user-defined function]
|
||||
* An xref:cassandra:developing/cql/operators.adoc#arithmetic_operators[arithmetic operation] between terms
|
||||
* A type hint
|
||||
* A bind marker, which denotes a variable to be bound at execution time.
|
||||
See the section on `prepared-statements` for details. A bind marker can
|
||||
|
|
@ -171,7 +170,7 @@ this documentation (see links above):
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/cql_statement.bnf[]
|
||||
include::cassandra:example$BNF/cql_statement.bnf[]
|
||||
----
|
||||
|
||||
== Prepared Statements
|
||||
|
|
|
|||
|
|
@ -10,35 +10,35 @@ Querying data from data is done using a `SELECT` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/select_statement.bnf[]
|
||||
include::cassandra:example$BNF/select_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/select_statement.cql[]
|
||||
include::cassandra:example$CQL/select_statement.cql[]
|
||||
----
|
||||
|
||||
The `SELECT` statements reads one or more columns for one or more rows
|
||||
in a table. It returns a result-set of the rows matching the request,
|
||||
where each row contains the values for the selection corresponding to
|
||||
the query. Additionally, xref:cql/functions.adoc#cql-functions[functions] including
|
||||
xref:cql/functions.adoc#aggregate-functions[aggregations] can be applied to the result.
|
||||
the query. Additionally, xref:cassandra:developing/cql/functions.adoc#cql-functions[functions] including
|
||||
xref:cassandra:developing/cql/functions.adoc#aggregate-functions[aggregations] can be applied to the result.
|
||||
|
||||
A `SELECT` statement contains at least a xref:cql/dml.adoc#selection-clause[selection clause] and the name of the table on which
|
||||
the selection is executed.
|
||||
CQL does *not* execute joins or sub-queries and a select statement only apply to a single table.
|
||||
A select statement can also have a xref:cql/dml.adoc#where-clause[where clause] that can further narrow the query results.
|
||||
Additional clauses can xref:cql/dml.adoc#ordering-clause[order] or xref:cql/dml.adoc#limit-clause[limit] the results.
|
||||
Lastly, xref:cql/dml.adoc#allow-filtering[queries that require full cluster filtering] can append `ALLOW FILTERING` to any query.
|
||||
A `SELECT` statement contains at least a xref:cassandra:developing/cql/dml.adoc#selection-clause[selection clause] and the name of the table on which
|
||||
the selection is executed.
|
||||
CQL does *not* execute joins or sub-queries and a select statement only apply to a single table.
|
||||
A select statement can also have a xref:cassandra:developing/cql/dml.adoc#where-clause[where clause] that can further narrow the query results.
|
||||
Additional clauses can xref:cassandra:developing/cql/dml.adoc#ordering-clause[order] or xref:cassandra:developing/cql/dml.adoc#limit-clause[limit] the results.
|
||||
Lastly, xref:cassandra:developing/cql/dml.adoc#allow-filtering[queries that require full cluster filtering] can append `ALLOW FILTERING` to any query.
|
||||
For virtual tables, from https://issues.apache.org/jira/browse/CASSANDRA-18238[CASSANDRA-18238], it is not necessary to specify `ALLOW FILTERING` when a query would normally require that. Please consult the documentation for virtual tables to know more.
|
||||
|
||||
[[selection-clause]]
|
||||
=== Selection clause
|
||||
|
||||
The `select_clause` determines which columns will be queried and returned in the result set.
|
||||
This clause can also apply transformations to apply to the result before returning.
|
||||
The `select_clause` determines which columns will be queried and returned in the result set.
|
||||
This clause can also apply transformations to apply to the result before returning.
|
||||
The selection clause consists of a comma-separated list of specific _selectors_ or, alternatively, the wildcard character (`*`) to select all the columns defined in the table.
|
||||
|
||||
==== Selectors
|
||||
|
|
@ -54,8 +54,8 @@ returned).
|
|||
* A casting, which allows to convert a nested selector to a (compatible)
|
||||
type.
|
||||
* A function call, where the arguments are selector themselves. See the
|
||||
section on xref:cql/functions.adoc#cql-functions[functions] for more details.
|
||||
* The special call `COUNT(*)` to the xref:cql/functions.adoc#count-function[COUNT function],
|
||||
section on xref:cassandra:developing/cql/functions.adoc#cql-functions[functions] for more details.
|
||||
* The special call `COUNT(*)` to the xref:cassandra:developing/cql/functions.adoc#count-function[COUNT function],
|
||||
which counts all non-null results.
|
||||
|
||||
==== Aliases
|
||||
|
|
@ -66,7 +66,7 @@ that of the alias. For instance:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/as.cql[]
|
||||
include::cassandra:example$CQL/as.cql[]
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
|
|
@ -97,26 +97,26 @@ user-defined types. In that case, the functions will return the list of timestam
|
|||
|
||||
The `WHERE` clause specifies which rows are queried. It specifies
|
||||
a relationship for `PRIMARY KEY` columns or a column that has
|
||||
a xref:cql/indexes.adoc#create-index-statement[secondary index] defined, along with a set value.
|
||||
a xref:cassandra:developing/cql/indexes.adoc#create-index-statement[secondary index] defined, along with a set value.
|
||||
|
||||
Not all relationships are allowed in a query. For instance, only an equality
|
||||
is allowed on a partition key. The `IN` clause is considered an equality for one or more values.
|
||||
The `TOKEN` clause can be used to query for partition key non-equalities.
|
||||
A partition key must be specified before clustering columns in the `WHERE` clause. The relationship
|
||||
A partition key must be specified before clustering columns in the `WHERE` clause. The relationship
|
||||
for clustering columns must specify a *contiguous* set of rows to order.
|
||||
|
||||
For instance, given:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/table_for_where.cql[]
|
||||
include::cassandra:example$CQL/table_for_where.cql[]
|
||||
----
|
||||
|
||||
The following query is allowed:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/where.cql[]
|
||||
include::cassandra:example$CQL/where.cql[]
|
||||
----
|
||||
|
||||
But the following one is not, as it does not select a contiguous set of
|
||||
|
|
@ -124,57 +124,57 @@ rows (and we suppose no secondary indexes are set):
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/where_fail.cql[]
|
||||
include::cassandra:example$CQL/where_fail.cql[]
|
||||
----
|
||||
|
||||
When specifying relationships, the `TOKEN` function can be applied to the `PARTITION KEY` column to query.
|
||||
When specifying relationships, the `TOKEN` function can be applied to the `PARTITION KEY` column to query.
|
||||
Rows will be selected based on the token of the `PARTITION_KEY` rather than on the value.
|
||||
[IMPORTANT]
|
||||
====
|
||||
The token of a key depends on the partitioner in use, and that
|
||||
in particular the `RandomPartitioner` won't yield a meaningful order.
|
||||
in particular the `RandomPartitioner` won't yield a meaningful order.
|
||||
Also note that ordering partitioners always order token values by bytes (so
|
||||
even if the partition key is of type int, `token(-1) > token(0)` in
|
||||
particular).
|
||||
particular).
|
||||
====
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/token.cql[]
|
||||
include::cassandra:example$CQL/token.cql[]
|
||||
----
|
||||
|
||||
The `IN` relationship is only allowed on the last column of the
|
||||
partition key or on the last column of the full primary key.
|
||||
|
||||
It is also possible to “group” `CLUSTERING COLUMNS` together in a
|
||||
relation using the tuple notation.
|
||||
relation using the tuple notation.
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/where_group_cluster_columns.cql[]
|
||||
include::cassandra:example$CQL/where_group_cluster_columns.cql[]
|
||||
----
|
||||
|
||||
This query will return all rows that sort after the one having “John's Blog” as
|
||||
`blog_tile` and '2012-01-01' for `posted_at` in the clustering order. In
|
||||
particular, rows having a `post_at <= '2012-01-01'` will be returned, as
|
||||
long as their `blog_title > 'John''s Blog'`.
|
||||
long as their `blog_title > 'John''s Blog'`.
|
||||
|
||||
That would not be the case for this example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/where_no_group_cluster_columns.cql[]
|
||||
include::cassandra:example$CQL/where_no_group_cluster_columns.cql[]
|
||||
----
|
||||
|
||||
The tuple notation may also be used for `IN` clauses on clustering columns:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/where_in_tuple.cql[]
|
||||
include::cassandra:example$CQL/where_in_tuple.cql[]
|
||||
----
|
||||
|
||||
The `CONTAINS` operator may only be used for collection columns (lists,
|
||||
|
|
@ -188,11 +188,11 @@ applies to the map keys.
|
|||
The `GROUP BY` option can condense all selected
|
||||
rows that share the same values for a set of columns into a single row.
|
||||
|
||||
Using the `GROUP BY` option, rows can be grouped at the partition key or clustering column level.
|
||||
Using the `GROUP BY` option, rows can be grouped at the partition key or clustering column level.
|
||||
Consequently, the `GROUP BY` option only accepts primary key columns in defined order as arguments.
|
||||
If a primary key column is restricted by an equality restriction, it is not included in the `GROUP BY` clause.
|
||||
|
||||
Aggregate functions will produce a separate value for each group.
|
||||
Aggregate functions will produce a separate value for each group.
|
||||
If no `GROUP BY` clause is specified, aggregates functions will produce a single value for all the rows.
|
||||
|
||||
If a column is selected without an aggregate function, in a statement
|
||||
|
|
@ -202,10 +202,10 @@ returned.
|
|||
[[ordering-clause]]
|
||||
=== Ordering results
|
||||
|
||||
The `ORDER BY` clause selects the order of the returned results.
|
||||
The argument is a list of column names and each column's order
|
||||
The `ORDER BY` clause selects the order of the returned results.
|
||||
The argument is a list of column names and each column's order
|
||||
(`ASC` for ascendant and `DESC` for descendant,
|
||||
The possible orderings are limited by the xref:cql/ddl.adoc#clustering-order[clustering order] defined on the table:
|
||||
The possible orderings are limited by the xref:cassandra:developing/cql/ddl.adoc#clustering-order[clustering order] defined on the table:
|
||||
|
||||
* if the table has been defined without any specific `CLUSTERING ORDER`, then the order is as defined by the clustering columns
|
||||
or the reverse
|
||||
|
|
@ -221,47 +221,47 @@ number of rows returned for a given partition by the query. Both types of limits
|
|||
[[allow-filtering]]
|
||||
=== Allowing filtering
|
||||
|
||||
By default, CQL only allows select queries that don't involve a full scan of all partitions.
|
||||
If all partitions are scanned, then returning the results may experience a significant latency proportional to the
|
||||
amount of data in the table. The `ALLOW FILTERING` option explicitly executes a full scan. Thus, the performance of
|
||||
By default, CQL only allows select queries that don't involve a full scan of all partitions.
|
||||
If all partitions are scanned, then returning the results may experience a significant latency proportional to the
|
||||
amount of data in the table. The `ALLOW FILTERING` option explicitly executes a full scan. Thus, the performance of
|
||||
the query can be unpredictable.
|
||||
|
||||
For example, consider the following table of user profiles with birth year and country of residence.
|
||||
For example, consider the following table of user profiles with birth year and country of residence.
|
||||
The birth year has a secondary index defined.
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/allow_filtering.cql[]
|
||||
include::cassandra:example$CQL/allow_filtering.cql[]
|
||||
----
|
||||
|
||||
The following queries are valid:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/query_allow_filtering.cql[]
|
||||
include::cassandra:example$CQL/query_allow_filtering.cql[]
|
||||
----
|
||||
|
||||
In both cases, the query performance is proportional to the amount of data returned.
|
||||
In both cases, the query performance is proportional to the amount of data returned.
|
||||
The first query returns all rows, because all users are selected.
|
||||
The second query returns only the rows defined by the secondary index, a per-node implementation; the results will
|
||||
depend on the number of nodes in the cluster, and is indirectly proportional to the amount of data stored.
|
||||
The number of nodes will always be multiple number of magnitude lower than the number of user profiles stored.
|
||||
The number of nodes will always be multiple number of magnitude lower than the number of user profiles stored.
|
||||
Both queries may return very large result sets, but the addition of a `LIMIT` clause can reduced the latency.
|
||||
|
||||
The following query will be rejected:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/query_fail_allow_filtering.cql[]
|
||||
include::cassandra:example$CQL/query_fail_allow_filtering.cql[]
|
||||
----
|
||||
|
||||
Cassandra cannot guarantee that large amounts of data won't have to scanned amount of data, even if the result is small.
|
||||
If you know that the dataset is small, and the performance will be reasonable, add `ALLOW FILTERING` to allow the query to
|
||||
Cassandra cannot guarantee that large amounts of data won't have to scanned amount of data, even if the result is small.
|
||||
If you know that the dataset is small, and the performance will be reasonable, add `ALLOW FILTERING` to allow the query to
|
||||
execute:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/query_nofail_allow_filtering.cql[]
|
||||
include::cassandra:example$CQL/query_nofail_allow_filtering.cql[]
|
||||
----
|
||||
|
||||
[[insert-statement]]
|
||||
|
|
@ -271,33 +271,33 @@ Inserting data for a row is done using an `INSERT` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/insert_statement.bnf[]
|
||||
include::cassandra:example$BNF/insert_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/insert_statement.cql[]
|
||||
include::cassandra:example$CQL/insert_statement.cql[]
|
||||
----
|
||||
|
||||
The `INSERT` statement writes one or more columns for a given row in a
|
||||
table.
|
||||
Since a row is identified by its `PRIMARY KEY`, at least one columns must be specified.
|
||||
The list of columns to insert must be supplied with the `VALUES` syntax.
|
||||
When using the `JSON` syntax, `VALUES` are optional.
|
||||
See the section on xref:cql/dml.adoc#cql-json[JSON support] for more detail.
|
||||
table.
|
||||
Since a row is identified by its `PRIMARY KEY`, at least one columns must be specified.
|
||||
The list of columns to insert must be supplied with the `VALUES` syntax.
|
||||
When using the `JSON` syntax, `VALUES` are optional.
|
||||
See the section on xref:cassandra:developing/cql/dml.adoc#cql-json[JSON support] for more detail.
|
||||
All updates for an `INSERT` are applied atomically and in isolation.
|
||||
|
||||
Unlike in SQL, `INSERT` does not check the prior existence of the row by default.
|
||||
The row is created if none existed before, and updated otherwise.
|
||||
Unlike in SQL, `INSERT` does not check the prior existence of the row by default.
|
||||
The row is created if none existed before, and updated otherwise.
|
||||
Furthermore, there is no means of knowing which action occurred.
|
||||
|
||||
The `IF NOT EXISTS` condition can restrict the insertion if the row does not exist.
|
||||
The `IF NOT EXISTS` condition can restrict the insertion if the row does not exist.
|
||||
However, note that using `IF NOT EXISTS` will incur a non-negligible performance cost, because Paxos is used,
|
||||
so this should be used sparingly.
|
||||
|
||||
Please refer to the xref:cql/dml.adoc#update-parameters[UPDATE] section for informations on the `update_parameter`.
|
||||
Please refer to the xref:cassandra:developing/cql/dml.adoc#update-parameters[UPDATE] section for informations on the `update_parameter`.
|
||||
Also note that `INSERT` does not support counters, while `UPDATE` does.
|
||||
|
||||
[[update-statement]]
|
||||
|
|
@ -307,19 +307,19 @@ Updating a row is done using an `UPDATE` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/update_statement.bnf[]
|
||||
include::cassandra:example$BNF/update_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/update_statement.cql[]
|
||||
include::cassandra:example$CQL/update_statement.cql[]
|
||||
----
|
||||
|
||||
The `UPDATE` statement writes one or more columns for a given row in a
|
||||
table.
|
||||
The `WHERE` clause is used to select the row to update and must include all columns of the `PRIMARY KEY`.
|
||||
table.
|
||||
The `WHERE` clause is used to select the row to update and must include all columns of the `PRIMARY KEY`.
|
||||
Non-primary key columns are set using the `SET` keyword.
|
||||
In an `UPDATE` statement, all updates within the same partition key are applied atomically and in isolation.
|
||||
|
||||
|
|
@ -332,14 +332,14 @@ However, like the `IF NOT EXISTS` condition, a non-negligible performance cost c
|
|||
|
||||
Regarding the `SET` assignment:
|
||||
|
||||
* `c = c + 3` will increment/decrement counters, the only operation allowed.
|
||||
* `c = c + 3` will increment/decrement counters, the only operation allowed.
|
||||
The column name after the '=' sign *must* be the same than the one before the '=' sign.
|
||||
Increment/decrement is only allowed on counters.
|
||||
See the section on xref:cql/dml.adoc#counters[counters] for details.
|
||||
* `id = id + <some-collection>` and `id[value1] = value2` are for collections.
|
||||
See the xref:cql/types.adoc#collections[collections] for details.
|
||||
* `id.field = 3` is for setting the value of a field on a non-frozen user-defined types.
|
||||
See the xref:cql/types.adoc#udts[UDTs] for details.
|
||||
Increment/decrement is only allowed on counters.
|
||||
See the section on xref:cassandra:developing/cql/dml.adoc#counters[counters] for details.
|
||||
* `id = id + <some-collection>` and `id[value1] = value2` are for collections.
|
||||
See the xref:cassandra:developing/cql/types.adoc#collections[collections] for details.
|
||||
* `id.field = 3` is for setting the value of a field on a non-frozen user-defined types.
|
||||
See the xref:cassandra:developing/cql/types.adoc#udts[UDTs] for details.
|
||||
|
||||
=== Update parameters
|
||||
|
||||
|
|
@ -369,14 +369,14 @@ Deleting rows or parts of rows uses the `DELETE` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/delete_statement.bnf[]
|
||||
include::cassandra:example$BNF/delete_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/delete_statement.cql[]
|
||||
include::cassandra:example$CQL/delete_statement.cql[]
|
||||
----
|
||||
|
||||
The `DELETE` statement deletes columns and rows. If column names are
|
||||
|
|
@ -389,7 +389,7 @@ may be deleted with one statement by using an `IN` operator. A range of
|
|||
rows may be deleted using an inequality operator (such as `>=`).
|
||||
|
||||
`DELETE` supports the `TIMESTAMP` option with the same semantics as in
|
||||
xref:cql/dml.adoc#update-parameters[updates].
|
||||
xref:cassandra:developing/cql/dml.adoc#update-parameters[updates].
|
||||
|
||||
In a `DELETE` statement, all deletions within the same partition key are
|
||||
applied atomically and in isolation.
|
||||
|
|
@ -407,14 +407,14 @@ statement by grouping them through a `BATCH` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/batch_statement.bnf[]
|
||||
include::cassandra:example$BNF/batch_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/batch_statement.cql[]
|
||||
include::cassandra:example$CQL/batch_statement.cql[]
|
||||
----
|
||||
|
||||
The `BATCH` statement group multiple modification statements
|
||||
|
|
@ -428,7 +428,7 @@ multiple updates.
|
|||
performed in isolation.
|
||||
* By default, all operations in the batch are performed as _logged_, to
|
||||
ensure all mutations eventually complete (or none will). See the notes
|
||||
on xref:cql/dml.adoc#unlogged-batches[UNLOGGED batches] for more details.
|
||||
on xref:cassandra:developing/cql/dml.adoc#unlogged-batches[UNLOGGED batches] for more details.
|
||||
|
||||
Note that:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
// Need some intro for UDF and native functions in general and point those to it.
|
||||
// [[cql-functions]][[native-functions]]
|
||||
|
||||
== Functions
|
||||
// Need some intro for UDF and native functions in general and point those to it.
|
||||
// [[cql-functions]][[native-functions]]
|
||||
= Functions
|
||||
|
||||
CQL supports 2 main categories of functions:
|
||||
|
||||
* xref:cql/functions.adoc#scalar-functions[scalar functions] that take a number of values and produce an output
|
||||
* xref:cql/functions.adoc#aggregate-functions[aggregate functions] that aggregate multiple rows resulting from a `SELECT` statement
|
||||
* xref:cassandra:developing/cql/functions.adoc#scalar-functions[scalar functions] that take a number of values and produce an output
|
||||
* xref:cassandra:developing/cql/functions.adoc#aggregate-functions[aggregate functions] that aggregate multiple rows resulting from a `SELECT` statement
|
||||
|
||||
In both cases, CQL provides a number of native "hard-coded" functions as
|
||||
well as the ability to create new user-defined functions.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
By default, the use of user-defined functions is disabled by default for
|
||||
security concerns (even when enabled, the execution of user-defined
|
||||
|
|
@ -26,15 +24,15 @@ A function is identifier by its name:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/function.bnf[]
|
||||
include::cassandra:example$BNF/function.bnf[]
|
||||
----
|
||||
|
||||
=== Scalar functions
|
||||
== Scalar functions
|
||||
|
||||
[[scalar-native-functions]]
|
||||
==== Native functions
|
||||
=== Native functions
|
||||
|
||||
===== Cast
|
||||
==== Cast
|
||||
|
||||
The `cast` function can be used to converts one native datatype to
|
||||
another.
|
||||
|
|
@ -99,9 +97,9 @@ double value 1 will be converted to the text value '1.0'. For instance:
|
|||
SELECT avg(cast(count as double)) FROM myTable
|
||||
----
|
||||
|
||||
===== Token
|
||||
==== Token
|
||||
|
||||
The `token` function computes the token for a given partition key.
|
||||
The `token` function computes the token for a given partition key.
|
||||
The exact signature of the token function depends on the table concerned and the partitioner used by the cluster.
|
||||
|
||||
The type of the arguments of the `token` depend on the partition key column type. The returned type depends on the defined partitioner:
|
||||
|
|
@ -118,32 +116,32 @@ For example, consider the following table:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table_simple.cql[]
|
||||
include::cassandra:example$CQL/create_table_simple.cql[]
|
||||
----
|
||||
|
||||
The table uses the default Murmur3Partitioner.
|
||||
The `token` function uses the single argument `text`, because the partition key is `userid` of text type.
|
||||
The returned type will be `bigint`.
|
||||
|
||||
===== Uuid
|
||||
==== Uuid
|
||||
|
||||
The `uuid` function takes no parameters and generates a random type 4
|
||||
uuid suitable for use in `INSERT` or `UPDATE` statements.
|
||||
|
||||
===== Timeuuid functions
|
||||
==== Timeuuid functions
|
||||
|
||||
====== `now`
|
||||
===== `now`
|
||||
|
||||
The `now` function takes no arguments and generates, on the coordinator
|
||||
node, a new unique timeuuid at the time the function is invoked. Note
|
||||
that this method is useful for insertion but is largely non-sensical in
|
||||
`WHERE` clauses.
|
||||
`WHERE` clauses.
|
||||
|
||||
For example, a query of the form:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/timeuuid_now.cql[]
|
||||
include::cassandra:example$CQL/timeuuid_now.cql[]
|
||||
----
|
||||
|
||||
will not return a result, by design, since the value returned by
|
||||
|
|
@ -151,7 +149,7 @@ will not return a result, by design, since the value returned by
|
|||
|
||||
`current_timeuuid` is an alias of `now`.
|
||||
|
||||
====== `min_timeuuid` and `max_timeuuid`
|
||||
===== `min_timeuuid` and `max_timeuuid`
|
||||
|
||||
The `min_timeuuid` function takes a `timestamp` value `t`, either a timestamp or a date string.
|
||||
It returns a _fake_ `timeuuid` corresponding to the _smallest_ possible `timeuuid` for timestamp `t`.
|
||||
|
|
@ -161,24 +159,23 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/timeuuid_min_max.cql[]
|
||||
include::cassandra:example$CQL/timeuuid_min_max.cql[]
|
||||
----
|
||||
|
||||
will select all rows where the `timeuuid` column `t` is later than `'2013-01-01 00:05+0000'` and earlier than `'2013-02-02 10:00+0000'`.
|
||||
will select all rows where the `timeuuid` column `t` is later than `'2013-01-01 00:05+0000'` and earlier than `'2013-02-02 10:00+0000'`.
|
||||
The clause `t >= maxTimeuuid('2013-01-01 00:05+0000')` would still _not_ select a `timeuuid` generated exactly at '2013-01-01 00:05+0000', and is essentially equivalent to `t > maxTimeuuid('2013-01-01 00:05+0000')`.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
The values generated by `min_timeuuid` and `max_timeuuid` are called _fake_ UUID because they do no respect the time-based UUID generation process
|
||||
specified by the http://www.ietf.org/rfc/rfc4122.txt[IETF RFC 4122].
|
||||
In particular, the value returned by these two methods will not be unique.
|
||||
Thus, only use these methods for *querying*, not for *insertion*, to prevent possible data overwriting.
|
||||
Thus, only use these methods for *querying*, not for *insertion*, to prevent possible data overwriting.
|
||||
====
|
||||
|
||||
===== Datetime functions
|
||||
==== Datetime functions
|
||||
|
||||
====== Retrieving the current date/time
|
||||
===== Retrieving the current date/time
|
||||
|
||||
The following functions can be used to retrieve the date/time at the
|
||||
time where the function is invoked:
|
||||
|
|
@ -200,10 +197,10 @@ For example the last two days of data can be retrieved using:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/current_date.cql[]
|
||||
include::cassandra:example$CQL/current_date.cql[]
|
||||
----
|
||||
|
||||
====== Time conversion functions
|
||||
===== Time conversion functions
|
||||
|
||||
A number of functions are provided to convert a `timeuuid`, a `timestamp` or a `date` into another `native` type.
|
||||
|
||||
|
|
@ -226,15 +223,15 @@ A number of functions are provided to convert a `timeuuid`, a `timestamp` or a `
|
|||
| `to_unix_timestamp` | `date` | Converts the `date` argument into a `bigInt` raw value
|
||||
|===
|
||||
|
||||
===== Blob conversion functions
|
||||
==== Blob conversion functions
|
||||
|
||||
A number of functions are provided to convert the native types into
|
||||
binary data, or a `blob`.
|
||||
For every xref:cql/types.adoc#native-types[type] supported by CQL, the function `type_as_blob` takes a argument of type `type` and returns it as a `blob`.
|
||||
binary data, or a `blob`.
|
||||
For every xref:cassandra:developing/cql/types.adoc#native-types[type] supported by CQL, the function `type_as_blob` takes a argument of type `type` and returns it as a `blob`.
|
||||
Conversely, the function `blob_as_type` takes a 64-bit `blob` argument and converts it to a `bigint` value.
|
||||
For example, `bigint_as_blob(3)` returns `0x0000000000000003` and `blob_as_bigint(0x0000000000000003)` returns `3`.
|
||||
|
||||
===== Math Functions
|
||||
==== Math Functions
|
||||
|
||||
Cql provides the following math functions: `abs`, `exp`, `log`, `log10`, and `round`.
|
||||
The return type for these functions is always the same as the input type.
|
||||
|
|
@ -254,7 +251,7 @@ The return type for these functions is always the same as the input type.
|
|||
|`round` | Rounds the input to the nearest whole number using rounding mode `HALF_UP`.
|
||||
|===
|
||||
|
||||
===== Collection functions
|
||||
==== Collection functions
|
||||
|
||||
A number of functions are provided to operate on collection columns.
|
||||
|
||||
|
|
@ -278,31 +275,30 @@ A number of functions are provided to operate on collection columns.
|
|||
|===
|
||||
|
||||
[[data-masking-functions]]
|
||||
===== Data masking functions
|
||||
==== Data masking functions
|
||||
|
||||
A number of functions allow to obscure the real contents of a column containing sensitive data.
|
||||
|
||||
include::partial$masking_functions.adoc[]
|
||||
include::cassandra:partial$masking_functions.adoc[]
|
||||
|
||||
[[vector-similarity-functions]]
|
||||
===== Vector similarity functions
|
||||
|
||||
A number of functions allow to obtain the similarity score between vectors of floats.
|
||||
|
||||
include::partial$vector_functions.adoc[]
|
||||
include::cassandra:partial$vector-search/vector_functions.adoc[]
|
||||
|
||||
[[user-defined-scalar-functions]]
|
||||
==== User-defined functions
|
||||
=== User-defined functions
|
||||
|
||||
User-defined functions (UDFs) execute user-provided code in Cassandra.
|
||||
User-defined functions (UDFs) execute user-provided code in Cassandra.
|
||||
By default, Cassandra supports defining functions in _Java_.
|
||||
|
||||
UDFs are part of the Cassandra schema, and are automatically propagated to all nodes in the cluster.
|
||||
UDFs are part of the Cassandra schema, and are automatically propagated to all nodes in the cluster.
|
||||
UDFs can be _overloaded_, so that multiple UDFs with different argument types can have the same function name.
|
||||
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
_JavaScript_ user-defined functions have been deprecated in Cassandra 4.1. In preparation for Cassandra 5.0, their removal is
|
||||
already in progress. For more information - CASSANDRA-17281, CASSANDRA-18252.
|
||||
|
|
@ -312,72 +308,72 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/function_overload.cql[]
|
||||
include::cassandra:example$CQL/function_overload.cql[]
|
||||
----
|
||||
|
||||
UDFs are susceptible to all of the normal problems with the chosen programming language.
|
||||
Accordingly, implementations should be safe against null pointer exceptions, illegal arguments, or any other potential source of exceptions.
|
||||
UDFs are susceptible to all of the normal problems with the chosen programming language.
|
||||
Accordingly, implementations should be safe against null pointer exceptions, illegal arguments, or any other potential source of exceptions.
|
||||
An exception during function execution will result in the entire statement failing.
|
||||
Valid queries for UDF use are `SELECT`, `INSERT` and `UPDATE` statements.
|
||||
|
||||
_Complex_ types like collections, tuple types and user-defined types are valid argument and return types in UDFs.
|
||||
_Complex_ types like collections, tuple types and user-defined types are valid argument and return types in UDFs.
|
||||
Tuple types and user-defined types use the DataStax Java Driver conversion functions.
|
||||
Please see the Java Driver documentation for details on handling tuple types and user-defined types.
|
||||
|
||||
Arguments for functions can be literals or terms.
|
||||
Arguments for functions can be literals or terms.
|
||||
Prepared statement placeholders can be used, too.
|
||||
|
||||
Note the use the double dollar-sign syntax to enclose the UDF source code.
|
||||
Note the use the double dollar-sign syntax to enclose the UDF source code.
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/function_dollarsign.cql[]
|
||||
include::cassandra:example$CQL/function_dollarsign.cql[]
|
||||
----
|
||||
|
||||
The implicitly available `udfContext` field (or binding for script UDFs) provides the necessary functionality to create new UDT and tuple values:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/function_udfcontext.cql[]
|
||||
include::cassandra:example$CQL/function_udfcontext.cql[]
|
||||
----
|
||||
|
||||
The definition of the `UDFContext` interface can be found in the Apache Cassandra source code for `org.apache.cassandra.cql3.functions.UDFContext`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::example$JAVA/udfcontext.java[]
|
||||
include::cassandra:example$JAVA/udfcontext.java[]
|
||||
----
|
||||
|
||||
Java UDFs already have some imports for common interfaces and classes defined. These imports are:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::example$JAVA/udf_imports.java[]
|
||||
include::cassandra:example$JAVA/udf_imports.java[]
|
||||
----
|
||||
|
||||
Please note, that these convenience imports are not available for script UDFs.
|
||||
|
||||
[[create-function-statement]]
|
||||
==== CREATE FUNCTION statement
|
||||
=== CREATE FUNCTION statement
|
||||
|
||||
Creating a new user-defined function uses the `CREATE FUNCTION` statement:
|
||||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/create_function_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_function_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_function.cql[]
|
||||
include::cassandra:example$CQL/create_function.cql[]
|
||||
----
|
||||
|
||||
`CREATE FUNCTION` with the optional `OR REPLACE` keywords creates either a function or replaces an existing one with the same signature.
|
||||
A `CREATE FUNCTION` without `OR REPLACE` fails if a function with the same signature already exists.
|
||||
`CREATE FUNCTION` with the optional `OR REPLACE` keywords creates either a function or replaces an existing one with the same signature.
|
||||
A `CREATE FUNCTION` without `OR REPLACE` fails if a function with the same signature already exists.
|
||||
If the optional `IF NOT EXISTS` keywords are used, the function will only be created only if another function with the same signature does not
|
||||
exist.
|
||||
`OR REPLACE` and `IF NOT EXISTS` cannot be used together.
|
||||
|
|
@ -387,48 +383,48 @@ Behavior for `null` input values must be defined for each function:
|
|||
* `RETURNS NULL ON NULL INPUT` declares that the function will always return `null` if any of the input arguments is `null`.
|
||||
* `CALLED ON NULL INPUT` declares that the function will always be executed.
|
||||
|
||||
===== Function Signature
|
||||
==== Function Signature
|
||||
|
||||
Signatures are used to distinguish individual functions. The signature consists of a fully-qualified function name of the <keyspace>.<function_name> and a concatenated list of all the argument types.
|
||||
|
||||
Note that keyspace names, function names and argument types are subject to the default naming conventions and case-sensitivity rules.
|
||||
|
||||
Functions belong to a keyspace; if no keyspace is specified, the current keyspace is used.
|
||||
Functions belong to a keyspace; if no keyspace is specified, the current keyspace is used.
|
||||
User-defined functions are not allowed in the system keyspaces.
|
||||
|
||||
[[drop-function-statement]]
|
||||
==== DROP FUNCTION statement
|
||||
=== DROP FUNCTION statement
|
||||
|
||||
Dropping a function uses the `DROP FUNCTION` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/drop_function_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_function_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/drop_function.cql[]
|
||||
include::cassandra:example$CQL/drop_function.cql[]
|
||||
----
|
||||
|
||||
You must specify the argument types of the function, the arguments_signature, in the drop command if there are multiple overloaded functions with the same name but different signatures.
|
||||
You must specify the argument types of the function, the arguments_signature, in the drop command if there are multiple overloaded functions with the same name but different signatures.
|
||||
`DROP FUNCTION` with the optional `IF EXISTS` keywords drops a function if it exists, but does not throw an error if it doesn't.
|
||||
|
||||
[[aggregate-functions]]
|
||||
=== Aggregate functions
|
||||
== Aggregate functions
|
||||
|
||||
Aggregate functions work on a set of rows.
|
||||
Aggregate functions work on a set of rows.
|
||||
Values for each row are input, to return a single value for the set of rows aggregated.
|
||||
|
||||
If `normal` columns, `scalar functions`, `UDT` fields, `writetime`, or `ttl` are selected together with aggregate functions, the values
|
||||
returned for them will be the ones of the first row matching the query.
|
||||
|
||||
==== Native aggregates
|
||||
=== Native aggregates
|
||||
|
||||
[[count-function]]
|
||||
===== Count
|
||||
==== Count
|
||||
|
||||
The `count` function can be used to count the rows returned by a query.
|
||||
|
||||
|
|
@ -436,28 +432,28 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/count.cql[]
|
||||
include::cassandra:example$CQL/count.cql[]
|
||||
----
|
||||
|
||||
It also can count the non-null values of a given column:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/count_nonnull.cql[]
|
||||
include::cassandra:example$CQL/count_nonnull.cql[]
|
||||
----
|
||||
|
||||
===== Max and Min
|
||||
==== Max and Min
|
||||
|
||||
The `max` and `min` functions compute the maximum and the minimum value returned by a query for a given column.
|
||||
The `max` and `min` functions compute the maximum and the minimum value returned by a query for a given column.
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/min_max.cql[]
|
||||
include::cassandra:example$CQL/min_max.cql[]
|
||||
----
|
||||
|
||||
===== Sum
|
||||
==== Sum
|
||||
|
||||
The `sum` function sums up all the values returned by a query for a given column.
|
||||
|
||||
|
|
@ -467,7 +463,7 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/sum.cql[]
|
||||
include::cassandra:example$CQL/sum.cql[]
|
||||
----
|
||||
|
||||
The returned value is of the same type as the input values, so there is a risk of overflowing the type if the sum of the
|
||||
|
|
@ -476,10 +472,10 @@ type large enough to contain the type. For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/sum_with_cast.cql[]
|
||||
include::cassandra:example$CQL/sum_with_cast.cql[]
|
||||
----
|
||||
|
||||
===== Avg
|
||||
==== Avg
|
||||
|
||||
The `avg` function computes the average of all the values returned by a query for a given column.
|
||||
|
||||
|
|
@ -487,7 +483,7 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/avg.cql[]
|
||||
include::cassandra:example$CQL/avg.cql[]
|
||||
----
|
||||
|
||||
The average of an empty collection returns zero.
|
||||
|
|
@ -498,19 +494,19 @@ You can use type casting to cast to a type with the desired decimal precision. F
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/avg_with_cast.cql[]
|
||||
include::cassandra:example$CQL/avg_with_cast.cql[]
|
||||
----
|
||||
|
||||
[[user-defined-aggregates-functions]]
|
||||
==== User-Defined Aggregates (UDAs)
|
||||
=== User-Defined Aggregates (UDAs)
|
||||
|
||||
User-defined aggregates allow the creation of custom aggregate functions.
|
||||
User-defined aggregates allow the creation of custom aggregate functions.
|
||||
User-defined aggregates can be used in `SELECT` statement.
|
||||
|
||||
Each aggregate requires an _initial state_ of type `STYPE` defined with the `INITCOND`value (default value: `null`).
|
||||
The first argument of the state function must have type `STYPE`.
|
||||
The remaining arguments of the state function must match the types of the user-defined aggregate arguments.
|
||||
The state function is called once for each row, and the value returned by the state function becomes the new state.
|
||||
Each aggregate requires an _initial state_ of type `STYPE` defined with the `INITCOND`value (default value: `null`).
|
||||
The first argument of the state function must have type `STYPE`.
|
||||
The remaining arguments of the state function must match the types of the user-defined aggregate arguments.
|
||||
The state function is called once for each row, and the value returned by the state function becomes the new state.
|
||||
After all rows are processed, the optional `FINALFUNC` is executed with last state value as its argument.
|
||||
|
||||
The `STYPE` value is mandatory in order to distinguish possibly overloaded versions of the state and/or final function, since the
|
||||
|
|
@ -522,63 +518,63 @@ keyspace has been selected using the `USE` statement):
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/uda.cql[]
|
||||
include::cassandra:example$CQL/uda.cql[]
|
||||
----
|
||||
|
||||
[[create-aggregate-statement]]
|
||||
==== CREATE AGGREGATE statement
|
||||
=== CREATE AGGREGATE statement
|
||||
|
||||
Creating (or replacing) a user-defined aggregate function uses the
|
||||
`CREATE AGGREGATE` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/create_aggregate_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_aggregate_statement.bnf[]
|
||||
----
|
||||
|
||||
See above for a complete example.
|
||||
|
||||
The `CREATE AGGREGATE` command with the optional `OR REPLACE` keywords creates either an aggregate or replaces an existing one with the same
|
||||
signature.
|
||||
signature.
|
||||
A `CREATE AGGREGATE` without `OR REPLACE` fails if an aggregate with the same signature already exists.
|
||||
The `CREATE AGGREGATE` command with the optional `IF NOT EXISTS` keywords creates an aggregate if it does not already exist.
|
||||
The `OR REPLACE` and `IF NOT EXISTS` phrases cannot be used together.
|
||||
|
||||
The `STYPE` value defines the type of the state value and must be specified.
|
||||
The optional `INITCOND` defines the initial state value for the aggregate; the default value is `null`.
|
||||
The optional `INITCOND` defines the initial state value for the aggregate; the default value is `null`.
|
||||
A non-null `INITCOND` must be specified for state functions that are declared with `RETURNS NULL ON NULL INPUT`.
|
||||
|
||||
The `SFUNC` value references an existing function to use as the state-modifying function.
|
||||
The `SFUNC` value references an existing function to use as the state-modifying function.
|
||||
The first argument of the state function must have type `STYPE`.
|
||||
The remaining arguments of the state function must match the types of the user-defined aggregate arguments.
|
||||
The state function is called once for each row, and the value returned by the state function becomes the new state.
|
||||
State is not updated for state functions declared with `RETURNS NULL ON NULL INPUT` and called with `null`.
|
||||
After all rows are processed, the optional `FINALFUNC` is executed with last state value as its argument.
|
||||
It must take only one argument with type `STYPE`, but the return type of the `FINALFUNC` may be a different type.
|
||||
It must take only one argument with type `STYPE`, but the return type of the `FINALFUNC` may be a different type.
|
||||
A final function declared with `RETURNS NULL ON NULL INPUT` means that the aggregate's return value will be `null`, if the last state is `null`.
|
||||
|
||||
If no `FINALFUNC` is defined, the overall return type of the aggregate function is `STYPE`.
|
||||
If no `FINALFUNC` is defined, the overall return type of the aggregate function is `STYPE`.
|
||||
If a `FINALFUNC` is defined, it is the return type of that function.
|
||||
|
||||
[[drop-aggregate-statement]]
|
||||
==== DROP AGGREGATE statement
|
||||
=== DROP AGGREGATE statement
|
||||
|
||||
Dropping an user-defined aggregate function uses the `DROP AGGREGATE`
|
||||
statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/drop_aggregate_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_aggregate_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/drop_aggregate.cql[]
|
||||
include::cassandra:example$CQL/drop_aggregate.cql[]
|
||||
----
|
||||
|
||||
The `DROP AGGREGATE` statement removes an aggregate created using `CREATE AGGREGATE`.
|
||||
The `DROP AGGREGATE` statement removes an aggregate created using `CREATE AGGREGATE`.
|
||||
You must specify the argument types of the aggregate to drop if there are multiple overloaded aggregates with the same name but a
|
||||
different signature.
|
||||
|
||||
|
|
|
|||
|
|
@ -3,23 +3,24 @@
|
|||
This document describes the Cassandra Query Language
|
||||
(CQL) version 3.
|
||||
Note that this document describes the last version of the language.
|
||||
However, the xref:cql/changes.adoc[changes] section provides the differences between the versions of CQL since version 3.0.
|
||||
However, the xref:cassandra:developing/cql/changes.adoc[changes] section provides the differences between the versions of CQL since version 3.0.
|
||||
|
||||
CQL offers a model similar to SQL.
|
||||
The data is stored in *tables* containing *rows* of *columns*.
|
||||
For that reason, when used in this document, these terms (tables, rows and columns) have the same definition that they have in SQL.
|
||||
|
||||
* xref:cql/definitions.adoc[Definitions]
|
||||
* xref:cql/types.adoc[Data types]
|
||||
* xref:cql/ddl.adoc[Data definition language]
|
||||
* xref:cql/dml.adoc[Data manipulation language]
|
||||
* xref:cql/operators.adoc[Operators]
|
||||
* xref:cql/indexes.adoc[Secondary indexes]
|
||||
* xref:cql/mvs.adoc[Materialized views]
|
||||
* xref:cql/functions.adoc[Functions]
|
||||
* xref:cql/json.adoc[JSON]
|
||||
* xref:cql/security.adoc[CQL security]
|
||||
* xref:developing/cql/dynamic_data_masking.adoc[Dynamic data masking]
|
||||
* xref:cql/triggers.adoc[Triggers]
|
||||
* xref:cql/appendices.adoc[Appendices]
|
||||
* xref:cql/changes.adoc[Changes]
|
||||
|
||||
* xref:cassandra:developing/cql/definitions.adoc[Definitions]
|
||||
* xref:cassandra:developing/cql/types.adoc[Data types]
|
||||
* xref:cassandra:developing/cql/ddl.adoc[Data definition language]
|
||||
* xref:cassandra:developing/cql/dml.adoc[Data manipulation language]
|
||||
* xref:cassandra:developing/cql/operators.adoc[Operators]
|
||||
* xref:cassandra:developing/cql/indexes.adoc[Secondary indexes]
|
||||
* xref:cassandra:developing/cql/mvs.adoc[Materialized views]
|
||||
* xref:cassandra:developing/cql/functions.adoc[Functions]
|
||||
* xref:cassandra:developing/cql/json.adoc[JSON]
|
||||
* xref:cassandra:developing/cql/security.adoc[CQL security]
|
||||
* xref:cassandra:developing/cql/dynamic_data_masking.adoc[Dynamic data masking]
|
||||
* xref:cassandra:developing/cql/triggers.adoc[Triggers]
|
||||
* xref:cassandra:developing/cql/appendices.adoc[Appendices]
|
||||
* xref:cassandra:developing/cql/changes.adoc[Changes]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ name defined by:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/index_name.bnf[]
|
||||
include::cassandra:example$BNF/index_name.bnf[]
|
||||
----
|
||||
|
||||
[[create-index-statement]]
|
||||
|
|
@ -19,20 +19,20 @@ desired.
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/create_index_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_index_statement.bnf[]
|
||||
----
|
||||
|
||||
If data already exists for the column, it will be indexed
|
||||
asynchronously. After the index is created, new data for the column is
|
||||
indexed automatically at insertion time. Attempting to create an already
|
||||
existing index will return an error unless the `IF NOT EXISTS` option is used.
|
||||
indexed automatically at insertion time. Attempting to create an already
|
||||
existing index will return an error unless the `IF NOT EXISTS` option is used.
|
||||
If it is used, the statement will be a no-op if the index already exists.
|
||||
|
||||
*Examples*:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_index.cql[]
|
||||
include::cassandra:example$CQL/create_index.cql[]
|
||||
----
|
||||
|
||||
=== Index Types
|
||||
|
|
@ -59,7 +59,7 @@ Dropping a secondary index uses the `DROP INDEX` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/drop_index_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_index_statement.bnf[]
|
||||
----
|
||||
|
||||
The `DROP INDEX` statement is used to drop an existing secondary index.
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
= JSON Support
|
||||
|
||||
Cassandra 2.2 introduces JSON support to `SELECT <select-statement>` and
|
||||
`INSERT <insert-statement>` statements.
|
||||
`INSERT <insert-statement>` statements.
|
||||
This support does not fundamentally alter the CQL API (for example, the schema is still
|
||||
enforced).
|
||||
It simply provides a convenient way to work with JSON documents.
|
||||
|
||||
== SELECT JSON
|
||||
|
||||
With `SELECT` statements, the `JSON` keyword is used to return each row as a single `JSON` encoded map.
|
||||
With `SELECT` statements, the `JSON` keyword is used to return each row as a single `JSON` encoded map.
|
||||
The remainder of the `SELECT` statement behavior is the same.
|
||||
|
||||
The result map keys match the column names in a normal result set.
|
||||
For example, a statement like `SELECT JSON a, ttl(b) FROM ...` would result in a map with keys `"a"` and `"ttl(b)"`.
|
||||
However, there is one notable exception: for symmetry with `INSERT JSON` behavior, case-sensitive column names with upper-case letters will be surrounded with double quotes.
|
||||
The result map keys match the column names in a normal result set.
|
||||
For example, a statement like `SELECT JSON a, ttl(b) FROM ...` would result in a map with keys `"a"` and `"ttl(b)"`.
|
||||
However, there is one notable exception: for symmetry with `INSERT JSON` behavior, case-sensitive column names with upper-case letters will be surrounded with double quotes.
|
||||
For example, `SELECT JSON myColumn FROM ...` would result in a map key `"\"myColumn\""` with escaped quotes).
|
||||
|
||||
The map values will JSON-encoded representations (as described below) of the result set values.
|
||||
|
|
@ -29,7 +29,7 @@ two columns named "myKey" and "value", you would do the following:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/insert_json.cql[]
|
||||
include::cassandra:example$CQL/insert_json.cql[]
|
||||
----
|
||||
|
||||
By default (or if `DEFAULT NULL` is explicitly used), a column omitted
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Materialized views names are defined by:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/view_name.bnf[]
|
||||
include::cassandra:example$BNF/view_name.bnf[]
|
||||
----
|
||||
|
||||
[[create-materialized-view-statement]]
|
||||
|
|
@ -15,14 +15,14 @@ You can create a materialized view on a table using a
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/create_mv_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_mv_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_mv_statement.cql[]
|
||||
include::cassandra:example$CQL/create_mv_statement.cql[]
|
||||
----
|
||||
|
||||
The `CREATE MATERIALIZED VIEW` statement creates a new materialized
|
||||
|
|
@ -33,17 +33,16 @@ to the base table will cause corresponding updates in the view.
|
|||
|
||||
Creating a materialized view has 3 main parts:
|
||||
|
||||
* The xref:cql/mvs.adoc#mv-select[select statement] that restrict the data included in
|
||||
* The xref:cassandra:developing/cql/mvs.adoc#mv-select[select statement] that restrict the data included in
|
||||
the view.
|
||||
* The xref:cql/mvs.adoc#mv-primary-key[primary key] definition for the view.
|
||||
* The xref:cql/mvs.adoc#mv-options[options] for the view.
|
||||
* The xref:cassandra:developing/cql/mvs.adoc#mv-primary-key[primary key] definition for the view.
|
||||
* The xref:cassandra:developing/cql/mvs.adoc#mv-options[options] for the view.
|
||||
|
||||
Attempting to create an already existing materialized view will return
|
||||
an error unless the `IF NOT EXISTS` option is used. If it is used, the
|
||||
statement will be a no-op if the materialized view already exists.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
By default, materialized views are built in a single thread. The initial
|
||||
build can be parallelized by increasing the number of threads specified
|
||||
|
|
@ -60,21 +59,21 @@ The select statement of a materialized view creation defines which of
|
|||
the base table is included in the view. That statement is limited in a
|
||||
number of ways:
|
||||
|
||||
* the xref:cql/mvs.adoc#selection-clause[selection] is limited to those that only
|
||||
* the xref:cassandra:developing/cql/mvs.adoc#selection-clause[selection] is limited to those that only
|
||||
select columns of the base table. In other words, you can't use any
|
||||
function (aggregate or not), casting, term, etc. Aliases are also not
|
||||
supported.
|
||||
You can however use * as a shortcut of selecting all columns.
|
||||
Further, xref:cql/types.adoc#static-columns[static columns] cannot be included in a materialized view.
|
||||
supported.
|
||||
You can however use * as a shortcut of selecting all columns.
|
||||
Further, xref:cassandra:developing/cql/types.adoc#static-columns[static columns] cannot be included in a materialized view.
|
||||
Thus, a `SELECT *` command isn't allowed if the base table has static columns.
|
||||
The `WHERE` clause has the following restrictions:
|
||||
|
||||
** cannot include any `bind_marker`
|
||||
** cannot have columns that are not part of the _base table_ primary key that are not restricted by an `IS NOT NULL` restriction
|
||||
** cannot have columns that are not part of the _base table_ primary key that are not restricted by an `IS NOT NULL` restriction
|
||||
** no other restriction is allowed
|
||||
** cannot have columns that are part of the _view_ primary key be null, they must always be at least restricted by a `IS NOT NULL`
|
||||
restriction (or any other restriction, but they must have one).
|
||||
* cannot have an xref:cql/dml.adoc#ordering-clause[ordering clause], a xref:cql/dml.adoc#limit-clause[limit], or xref:cql/dml.adoc#allow-filtering[ALLOW FILTERING
|
||||
* cannot have an xref:cassandra:developing/cql/dml.adoc#ordering-clause[ordering clause], a xref:cassandra:developing/cql/dml.adoc#limit-clause[limit], or xref:cassandra:developing/cql/dml.adoc#allow-filtering[ALLOW FILTERING
|
||||
|
||||
=== MV primary key
|
||||
|
||||
|
|
@ -91,21 +90,21 @@ So for instance, give the following base table definition:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/mv_table_def.cql[]
|
||||
include::cassandra:example$CQL/mv_table_def.cql[]
|
||||
----
|
||||
|
||||
then the following view definitions are allowed:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/mv_table_from_base.cql[]
|
||||
include::cassandra:example$CQL/mv_table_from_base.cql[]
|
||||
----
|
||||
|
||||
but the following ones are *not* allowed:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/mv_table_error.cql[]
|
||||
include::cassandra:example$CQL/mv_table_error.cql[]
|
||||
----
|
||||
|
||||
=== MV options
|
||||
|
|
@ -122,7 +121,7 @@ the `ALTER MATERIALIZED VIEW` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/alter_mv_statement.bnf[]
|
||||
include::cassandra:example$BNF/alter_mv_statement.bnf[]
|
||||
----
|
||||
|
||||
The options that can be updated are the same than at creation time and
|
||||
|
|
@ -137,7 +136,7 @@ statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/drop_mv_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_mv_statement.bnf[]
|
||||
----
|
||||
|
||||
If the materialized view does not exists, the statement will return an
|
||||
|
|
@ -147,7 +146,6 @@ no-op.
|
|||
=== MV Limitations
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
Removal of columns not selected in the Materialized View (via
|
||||
`UPDATE base SET unselected_column = null` or
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ A `duration` can be added (+) or substracted (-) from a `timestamp` or a
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/datetime_arithmetic.cql[]
|
||||
include::cassandra:example$CQL/datetime_arithmetic.cql[]
|
||||
----
|
||||
|
||||
will select all the records with a value of `t` which is in the last 2
|
||||
|
|
|
|||
|
|
@ -1,38 +1,37 @@
|
|||
role_name ::= identifier | string= Security
|
||||
|
||||
// role_name ::= identifier | string= Security
|
||||
[[cql-roles]]
|
||||
== Database Roles
|
||||
= Database Roles
|
||||
|
||||
CQL uses database roles to represent users and group of users.
|
||||
Syntactically, a role is defined by:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/role_name.bnf[]
|
||||
include::cassandra:example$BNF/role_name.bnf[]
|
||||
----
|
||||
|
||||
|
||||
[[create-role-statement]]
|
||||
=== CREATE ROLE
|
||||
== CREATE ROLE
|
||||
|
||||
Creating a role uses the `CREATE ROLE` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/create_role_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_role_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_role.cql[]
|
||||
include::cassandra:example$CQL/create_role.cql[]
|
||||
----
|
||||
|
||||
By default roles do not possess `LOGIN` privileges or `SUPERUSER`
|
||||
status.
|
||||
|
||||
xref:cql/security.adoc#cql-permissions[Permissions] on database resources are granted to
|
||||
xref:cassandra:developing/cql/security.adoc#cql-permissions[Permissions] on database resources are granted to
|
||||
roles; types of resources include keyspaces, tables, functions and roles
|
||||
themselves. Roles may be granted to other roles to create hierarchical
|
||||
permissions structures; in these hierarchies, permissions and
|
||||
|
|
@ -44,13 +43,13 @@ acquire any roles and privileges granted to that role.
|
|||
|
||||
Only a client with with the `CREATE` permission on the database roles
|
||||
resource may issue `CREATE ROLE` requests (see the
|
||||
xref:cql/security.adoc#cql-permissions[relevant section]), unless the client is a
|
||||
xref:cassandra:developing/cql/security.adoc#cql-permissions[relevant section]), unless the client is a
|
||||
`SUPERUSER`. Role management in Cassandra is pluggable and custom
|
||||
implementations may support only a subset of the listed options.
|
||||
|
||||
Role names should be quoted if they contain non-alphanumeric characters.
|
||||
|
||||
==== Setting credentials for internal authentication
|
||||
=== Setting credentials for internal authentication
|
||||
|
||||
Use the `WITH PASSWORD` clause to set a password for internal
|
||||
authentication, enclosing the password in single quotation marks.
|
||||
|
|
@ -60,7 +59,7 @@ If internal authentication has not been set up or the role does not have
|
|||
|
||||
USE `WITH HASHED PASSWORD` to provide the jBcrypt hashed password directly. See the `hash_password` tool.
|
||||
|
||||
==== Restricting connections to specific datacenters
|
||||
=== Restricting connections to specific datacenters
|
||||
|
||||
If a `network_authorizer` has been configured, you can restrict login
|
||||
roles to specific datacenters with the `ACCESS TO DATACENTERS` clause
|
||||
|
|
@ -69,7 +68,7 @@ specifiying datacenters implicitly grants access to all datacenters. The
|
|||
clause `ACCESS TO ALL DATACENTERS` can be used for explicitness, but
|
||||
there's no functional difference.
|
||||
|
||||
==== Restricting connections from specific CIDR groups
|
||||
=== Restricting connections from specific CIDR groups
|
||||
|
||||
If a `cidr_authorizer` has been configured, you can restrict roles to login
|
||||
only from specific regions, aka CIDR groups, with the `ACCESS FROM CIDRS` clause
|
||||
|
|
@ -81,7 +80,7 @@ groups restrictions. Valid CIDR groups should be used with `ACCESS FROM CIDRS`
|
|||
clause. `nodetool list-cidrgroups` command can be used to see available CIDR groups
|
||||
in the Cluster.
|
||||
|
||||
==== Creating a role conditionally
|
||||
=== Creating a role conditionally
|
||||
|
||||
Attempting to create an existing role results in an invalid query
|
||||
condition unless the `IF NOT EXISTS` option is used. If the option is
|
||||
|
|
@ -89,30 +88,30 @@ used and the role exists, the statement is a no-op:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_role_ifnotexists.cql[]
|
||||
include::cassandra:example$CQL/create_role_ifnotexists.cql[]
|
||||
----
|
||||
|
||||
[[alter-role-statement]]
|
||||
=== ALTER ROLE
|
||||
== ALTER ROLE
|
||||
|
||||
Altering a role options uses the `ALTER ROLE` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/alter_role_statement.bnf[]
|
||||
include::cassandra:example$BNF/alter_role_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/alter_role.cql[]
|
||||
include::cassandra:example$CQL/alter_role.cql[]
|
||||
----
|
||||
If the role does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
|
||||
USE `WITH HASHED PASSWORD` to provide the jBcrypt hashed password directly. See the `hash_password` tool.
|
||||
|
||||
==== Restricting connections to specific datacenters
|
||||
=== Restricting connections to specific datacenters
|
||||
|
||||
If a `network_authorizer` has been configured, you can restrict login
|
||||
roles to specific datacenters with the `ACCESS TO DATACENTERS` clause
|
||||
|
|
@ -120,7 +119,7 @@ followed by a set literal of datacenters the user can access. To remove
|
|||
any data center restrictions, use the `ACCESS TO ALL DATACENTERS`
|
||||
clause.
|
||||
|
||||
==== Restricting connections from specific CIDR groups
|
||||
=== Restricting connections from specific CIDR groups
|
||||
|
||||
If a `cidr_authorizer` has been configured, you can restrict roles to login
|
||||
only from specific regions, aka CIDR groups, with the `ACCESS FROM CIDRS` clause
|
||||
|
|
@ -132,7 +131,7 @@ groups restrictions. Valid CIDR groups should be used with `ACCESS FROM CIDRS`
|
|||
clause. `nodetool list-cidrgroups` command can be used to see available CIDR groups
|
||||
in the Cluster.
|
||||
|
||||
==== Conditions on executing `ALTER ROLE` statements:
|
||||
=== Conditions on executing `ALTER ROLE` statements:
|
||||
|
||||
* a client must have `SUPERUSER` status to alter the `SUPERUSER` status
|
||||
of another role
|
||||
|
|
@ -144,13 +143,13 @@ identified at login (e.g. `PASSWORD`)
|
|||
`permission <cql-permissions>` on that role
|
||||
|
||||
[[drop-role-statement]]
|
||||
=== DROP ROLE
|
||||
== DROP ROLE
|
||||
|
||||
Dropping a role uses the `DROP ROLE` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/drop_role_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_role_statement.bnf[]
|
||||
----
|
||||
|
||||
`DROP ROLE` requires the client to have `DROP`
|
||||
|
|
@ -164,34 +163,33 @@ query condition unless the `IF EXISTS` option is used. If the option is
|
|||
used and the role does not exist the statement is a no-op.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
DROP ROLE intentionally does not terminate any open user sessions.
|
||||
Currently connected sessions will remain connected and will retain the
|
||||
ability to perform any database actions which do not require
|
||||
xref:cql/security.adoc#authorization[authorization].
|
||||
However, if authorization is enabled, xref:cql/security.adoc#cql-permissions[permissions] of the dropped role are also revoked,
|
||||
subject to the xref:cql/security.adoc#auth-caching[caching options] configured in xref:cql/configuring.adoc#cassandra.yaml[cassandra-yaml] file.
|
||||
xref:cassandra:developing/cql/security.adoc#authorization[authorization].
|
||||
However, if authorization is enabled, xref:cassandra:developing/cql/security.adoc#cql-permissions[permissions] of the dropped role are also revoked,
|
||||
subject to the xref:cassandra:developing/cql/security.adoc#auth-caching[caching options] configured in xref:cassandra:developing/cql/configuring.adoc#cassandra.yaml[cassandra-yaml] file.
|
||||
Should a dropped role be subsequently recreated and have new xref:security.adoc#grant-permission-statement[permissions] or
|
||||
xref:security.adoc#grant-role-statement[roles]` granted to it, any client sessions still
|
||||
connected will acquire the newly granted permissions and roles.
|
||||
====
|
||||
|
||||
[[grant-role-statement]]
|
||||
=== GRANT ROLE
|
||||
== GRANT ROLE
|
||||
|
||||
Granting a role to another uses the `GRANT ROLE` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/grant_role_statement.bnf[]
|
||||
include::cassandra:example$BNF/grant_role_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/grant_role.cql[]
|
||||
include::cassandra:example$CQL/grant_role.cql[]
|
||||
----
|
||||
|
||||
This statement grants the `report_writer` role to `alice`. Any
|
||||
|
|
@ -202,24 +200,24 @@ not permitted. The following examples result in error conditions:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/role_error.cql[]
|
||||
include::cassandra:example$CQL/role_error.cql[]
|
||||
----
|
||||
|
||||
[[revoke-role-statement]]
|
||||
=== REVOKE ROLE
|
||||
== REVOKE ROLE
|
||||
|
||||
Revoking a role uses the `REVOKE ROLE` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/revoke_role_statement.bnf[]
|
||||
include::cassandra:example$BNF/revoke_role_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/revoke_role.cql[]
|
||||
include::cassandra:example$CQL/revoke_role.cql[]
|
||||
----
|
||||
|
||||
This statement revokes the `report_writer` role from `alice`. Any
|
||||
|
|
@ -227,32 +225,32 @@ permissions that `alice` has acquired via the `report_writer` role are
|
|||
also revoked.
|
||||
|
||||
[[list-roles-statement]]
|
||||
=== LIST ROLES
|
||||
== LIST ROLES
|
||||
|
||||
All the known roles (in the system or granted to specific role) can be
|
||||
listed using the `LIST ROLES` statement:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/list_roles_statement.bnf[]
|
||||
include::cassandra:example$BNF/list_roles_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list_roles.cql[]
|
||||
include::cassandra:example$CQL/list_roles.cql[]
|
||||
----
|
||||
|
||||
returns all known roles in the system, this requires `DESCRIBE`
|
||||
permission on the database roles resource.
|
||||
permission on the database roles resource.
|
||||
|
||||
This example enumerates all roles granted to `alice`, including those transitively
|
||||
acquired:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list_roles_of.cql[]
|
||||
include::cassandra:example$CQL/list_roles_of.cql[]
|
||||
----
|
||||
|
||||
This example lists all roles directly granted to `bob` without including any of the
|
||||
|
|
@ -260,7 +258,7 @@ transitively acquired ones:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list_roles_nonrecursive.cql[]
|
||||
include::cassandra:example$CQL/list_roles_nonrecursive.cql[]
|
||||
----
|
||||
|
||||
== Users
|
||||
|
|
@ -279,22 +277,22 @@ Creating a user uses the `CREATE USER` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/create_user_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_user_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_user.cql[]
|
||||
include::cassandra:example$CQL/create_user.cql[]
|
||||
----
|
||||
|
||||
The `CREATE USER` command is equivalent to `CREATE ROLE` where the `LOGIN` option is `true`.
|
||||
The `CREATE USER` command is equivalent to `CREATE ROLE` where the `LOGIN` option is `true`.
|
||||
So, the following pairs of statements are equivalent:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_user_role.cql[]
|
||||
include::cassandra:example$CQL/create_user_role.cql[]
|
||||
----
|
||||
|
||||
[[alter-user-statement]]
|
||||
|
|
@ -304,14 +302,14 @@ Altering the options of a user uses the `ALTER USER` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/alter_user_statement.bnf[]
|
||||
include::cassandra:example$BNF/alter_user_statement.bnf[]
|
||||
----
|
||||
If the role does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/alter_user.cql[]
|
||||
include::cassandra:example$CQL/alter_user.cql[]
|
||||
----
|
||||
|
||||
[[drop-user-statement]]
|
||||
|
|
@ -321,7 +319,7 @@ Dropping a user uses the `DROP USER` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/drop_user_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_user_statement.bnf[]
|
||||
----
|
||||
|
||||
[[list-users-statement]]
|
||||
|
|
@ -331,7 +329,7 @@ Existing users can be listed using the `LIST USERS` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/list_users_statement.bnf[]
|
||||
include::cassandra:example$BNF/list_users_statement.bnf[]
|
||||
----
|
||||
|
||||
Note that this statement is equivalent to xref:security.adoc#list-roles-statement[`LIST ROLES], but only roles with the `LOGIN` privilege are included in the output.
|
||||
|
|
@ -403,7 +401,7 @@ and which statements are enabled by that permission.
|
|||
|
||||
| `ALTER` | `ALL KEYSPACES` | `ALTER KEYSPACE` and `ALTER TABLE` in any keyspace
|
||||
|
||||
| `ALTER` | `KEYSPACE` | `ALTER KEYSPACE` and `ALTER TABLE` in specified keyspace
|
||||
| `ALTER` | `KEYSPACE` | `ALTER KEYSPACE` and `ALTER TABLE` in specified keyspace
|
||||
|
||||
| `ALTER` | `TABLE` | `ALTER TABLE`
|
||||
|
||||
|
|
@ -441,7 +439,7 @@ and which statements are enabled by that permission.
|
|||
|
||||
| `SELECT` | `ALL MBEANS` | Call getter methods on any mbean
|
||||
|
||||
| `SELECT` | `MBEANS` | Call getter methods on any mbean matching a wildcard pattern
|
||||
| `SELECT` | `MBEANS` | Call getter methods on any mbean matching a wildcard pattern
|
||||
|
||||
| `SELECT` | `MBEAN` | Call getter methods on named mbean
|
||||
|
||||
|
|
@ -524,14 +522,14 @@ Granting a permission uses the `GRANT PERMISSION` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/grant_permission_statement.bnf[]
|
||||
include::cassandra:example$BNF/grant_permission_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/grant_perm.cql[]
|
||||
include::cassandra:example$CQL/grant_perm.cql[]
|
||||
----
|
||||
|
||||
This example gives any user with the role `data_reader` permission to execute
|
||||
|
|
@ -539,7 +537,7 @@ This example gives any user with the role `data_reader` permission to execute
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/grant_modify.cql[]
|
||||
include::cassandra:example$CQL/grant_modify.cql[]
|
||||
----
|
||||
|
||||
To give any user with the role `data_writer` permission to perform
|
||||
|
|
@ -548,7 +546,7 @@ tables in the `keyspace1` keyspace:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/grant_drop.cql[]
|
||||
include::cassandra:example$CQL/grant_drop.cql[]
|
||||
----
|
||||
|
||||
To give any user with the `schema_owner` role permissions to `DROP` a specific
|
||||
|
|
@ -556,7 +554,7 @@ To give any user with the `schema_owner` role permissions to `DROP` a specific
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/grant_execute.cql[]
|
||||
include::cassandra:example$CQL/grant_execute.cql[]
|
||||
----
|
||||
|
||||
This command grants any user with the `report_writer` role permission to execute
|
||||
|
|
@ -565,7 +563,7 @@ This command grants any user with the `report_writer` role permission to execute
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/grant_describe.cql[]
|
||||
include::cassandra:example$CQL/grant_describe.cql[]
|
||||
----
|
||||
|
||||
This grants any user with the `role_admin` role permission to view any
|
||||
|
|
@ -592,14 +590,14 @@ statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/revoke_permission_statement.bnf[]
|
||||
include::cassandra:example$BNF/revoke_permission_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/revoke_perm.cql[]
|
||||
include::cassandra:example$CQL/revoke_perm.cql[]
|
||||
----
|
||||
|
||||
Because of their function in normal driver operations, certain tables
|
||||
|
|
@ -609,7 +607,7 @@ their assigned role:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/no_revoke.cql[]
|
||||
include::cassandra:example$CQL/no_revoke.cql[]
|
||||
----
|
||||
|
||||
[[list-permissions-statement]]
|
||||
|
|
@ -619,14 +617,14 @@ Listing granted permissions uses the `LIST PERMISSIONS` statement:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/list_permissions_statement.bnf[]
|
||||
include::cassandra:example$BNF/list_permissions_statement.bnf[]
|
||||
----
|
||||
|
||||
For example:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list_perm.cql[]
|
||||
include::cassandra:example$CQL/list_perm.cql[]
|
||||
----
|
||||
|
||||
Show all permissions granted to `alice`, including those acquired
|
||||
|
|
@ -634,7 +632,7 @@ transitively from any other roles:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list_all_perm.cql[]
|
||||
include::cassandra:example$CQL/list_all_perm.cql[]
|
||||
----
|
||||
|
||||
Show all permissions on `keyspace1.table1` granted to `bob`, including
|
||||
|
|
@ -647,7 +645,7 @@ which were directly granted to `bob` or one of `bob`'s roles:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list_select_perm.cql[]
|
||||
include::cassandra:example$CQL/list_select_perm.cql[]
|
||||
----
|
||||
|
||||
Show any permissions granted to `carlos` or any of `carlos`'s roles,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Triggers are identified with a name defined by:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/trigger_name.bnf[]
|
||||
include::cassandra:example$BNF/trigger_name.bnf[]
|
||||
----
|
||||
|
||||
[[create-trigger-statement]]
|
||||
|
|
@ -14,14 +14,14 @@ Creating a new trigger uses the `CREATE TRIGGER` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/create_trigger_statement.bnf[]
|
||||
include::cassandra:example$BNF/create_trigger_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_trigger.cql[]
|
||||
include::cassandra:example$CQL/create_trigger.cql[]
|
||||
----
|
||||
|
||||
The actual logic that makes up the trigger can be written in any Java
|
||||
|
|
@ -39,12 +39,12 @@ Dropping a trigger uses the `DROP TRIGGER` statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/drop_trigger_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_trigger_statement.bnf[]
|
||||
----
|
||||
|
||||
For instance:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/drop_trigger.cql[]
|
||||
include::cassandra:example$CQL/drop_trigger.cql[]
|
||||
----
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
= Data Types
|
||||
|
||||
CQL is a typed language and supports a rich set of data types, including
|
||||
xref:cql/types.adoc#native-types[native types], xref:cql/types.adoc#collections[collection types],
|
||||
xref:cql/types.adoc#udts[user-defined types], xref:cql/types.adoc#tuples[tuple types], and xref:cql/types.adoc#custom-types[custom
|
||||
xref:cassandra:developing/cql/types.adoc#native-types[native types], xref:cassandra:developing/cql/types.adoc#collections[collection types],
|
||||
xref:cassandra:developing/cql/types.adoc#udts[user-defined types], xref:cassandra:developing/cql/types.adoc#tuples[tuple types], and xref:cassandra:developing/cql/types.adoc#custom-types[custom
|
||||
types]:
|
||||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/cql_type.bnf[]
|
||||
include::cassandra:example$BNF/cql_type.bnf[]
|
||||
----
|
||||
|
||||
== Native types
|
||||
|
|
@ -16,11 +16,11 @@ The native types supported by CQL are:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/native_type.bnf[]
|
||||
include::cassandra:example$BNF/native_type.bnf[]
|
||||
----
|
||||
|
||||
The following table gives additional informations on the native data
|
||||
types, and on which kind of xref:cql/definitions.adoc#constants[constants] each type supports:
|
||||
The following table gives additional information on the native data
|
||||
types, and on which kind of xref:cassandra:developing/cql/definitions.adoc#constants[constants] each type supports:
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|===
|
||||
|
|
@ -29,7 +29,7 @@ types, and on which kind of xref:cql/definitions.adoc#constants[constants] each
|
|||
| `ascii` | `string` | ASCII character string
|
||||
| `bigint` | `integer` | 64-bit signed long
|
||||
| `blob` | `blob` | Arbitrary bytes (no validation)
|
||||
| `boolean` | `boolean` | Either `true` or `false`
|
||||
| `boolean` | `boolean` | Either `true` or `false`
|
||||
| `counter` | `integer` | Counter column (64-bit signed value). See `counters` for details.
|
||||
| `date` | `integer`, `string` | A date (with no corresponding time value). See `dates` below for details.
|
||||
| `decimal` | `integer`, `float` | Variable-precision decimal
|
||||
|
|
@ -58,7 +58,7 @@ generally used as a “conflict-free” timestamp. Also see `timeuuid-functions`
|
|||
The `counter` type is used to define _counter columns_. A counter column
|
||||
is a column whose value is a 64-bit signed integer and on which 2
|
||||
operations are supported: incrementing and decrementing (see the
|
||||
xref:cql/dml.adoc#update-statement[UPDATE] statement for syntax).
|
||||
xref:cassandra:developing/cql/dml.adoc#update-statement[UPDATE] statement for syntax).
|
||||
Note that the value of a counter cannot
|
||||
be set: a counter does not exist until first incremented/decremented,
|
||||
and that first increment/decrement is made as if the prior value was 0.
|
||||
|
|
@ -70,7 +70,7 @@ Counters have a number of important limitations:
|
|||
* A table that contains a counter can only contain counters. In other
|
||||
words, either all the columns of a table outside the `PRIMARY KEY` have
|
||||
the `counter` type, or none of them have it.
|
||||
* Counters do not support xref:cql/dml.adoc#writetime-and-ttl-function[expiration].
|
||||
* Counters do not support xref:cassandra:developing/cql/dml.adoc#writetime-and-ttl-function[expiration].
|
||||
* The deletion of counters is supported, but is only guaranteed to work
|
||||
the first time you delete a counter. In other words, you should not
|
||||
re-update a counter that you have deleted (if you do, proper behavior is
|
||||
|
|
@ -116,7 +116,7 @@ feasible.
|
|||
The time of day may also be omitted (`'2011-02-03'` or
|
||||
`'2011-02-03+0000'`), in which case the time of day will default to
|
||||
00:00:00 in the specified or default time zone. However, if only the
|
||||
date part is relevant, consider using the xref:cql/types.adoc#dates[date] type.
|
||||
date part is relevant, consider using the xref:cassandra:developing/cql/types.adoc#dates[date] type.
|
||||
|
||||
[[dates]]
|
||||
== Date type
|
||||
|
|
@ -125,7 +125,7 @@ Values of the `date` type are encoded as 32-bit unsigned integers
|
|||
representing a number of days with “the epoch” at the center of the
|
||||
range (2^31). Epoch is January 1st, 1970
|
||||
|
||||
For xref:cql/types.adoc#timestamps[timestamps], a date can be input either as an
|
||||
For xref:cassandra:developing/cql/types.adoc#timestamps[timestamps], a date can be input either as an
|
||||
`integer` or using a date `string`. In the later case, the format should
|
||||
be `yyyy-mm-dd` (so `'2011-02-03'` for instance).
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ be `yyyy-mm-dd` (so `'2011-02-03'` for instance).
|
|||
Values of the `time` type are encoded as 64-bit signed integers
|
||||
representing the number of nanoseconds since midnight.
|
||||
|
||||
For xref:cql/types.adoc#timestamps[timestamps], a time can be input either as an
|
||||
For xref:cassandra:developing/cql/types.adoc#timestamps[timestamps], a time can be input either as an
|
||||
`integer` or using a `string` representing the time. In the later case,
|
||||
the format should be `hh:mm:ss[.fffffffff]` (where the sub-second
|
||||
precision is optional and if provided, can be less than the nanosecond).
|
||||
|
|
@ -178,7 +178,7 @@ For example:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/insert_duration.cql[]
|
||||
include::cassandra:example$CQL/insert_duration.cql[]
|
||||
----
|
||||
|
||||
[[duration-limitation]]
|
||||
|
|
@ -197,14 +197,14 @@ types of those collections is defined by:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/collection_type.bnf[]
|
||||
include::cassandra:example$BNF/collection_type.bnf[]
|
||||
----
|
||||
|
||||
and their values can be inputd using collection literals:
|
||||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/collection_literal.bnf[]
|
||||
include::cassandra:example$BNF/collection_literal.bnf[]
|
||||
----
|
||||
|
||||
Note however that neither `bind_marker` nor `NULL` are supported inside
|
||||
|
|
@ -227,7 +227,7 @@ has to be read (and reading one is not paged internally).
|
|||
* While insertion operations on sets and maps never incur a
|
||||
read-before-write internally, some operations on lists do. Further, some
|
||||
lists operations are not idempotent by nature (see the section on
|
||||
xref:cql/types.adoc#lists[lists] below for details), making their retry in case of
|
||||
xref:cassandra:developing/cql/types.adoc#lists[lists] below for details), making their retry in case of
|
||||
timeout problematic. It is thus advised to prefer sets over lists when
|
||||
possible.
|
||||
|
||||
|
|
@ -242,7 +242,7 @@ the map is sorted by its keys. You can define and insert a map with:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/map.cql[]
|
||||
include::cassandra:example$CQL/map.cql[]
|
||||
----
|
||||
|
||||
Further, maps support:
|
||||
|
|
@ -251,14 +251,14 @@ Further, maps support:
|
|||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/update_map.cql[]
|
||||
include::cassandra:example$CQL/update_map.cql[]
|
||||
----
|
||||
* Removing one or more element (if an element doesn't exist, removing it
|
||||
is a no-op but no error is thrown):
|
||||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/delete_map.cql[]
|
||||
include::cassandra:example$CQL/delete_map.cql[]
|
||||
----
|
||||
+
|
||||
Note that for removing multiple elements in a `map`, you remove from it
|
||||
|
|
@ -270,7 +270,7 @@ other words:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/update_ttl_map.cql[]
|
||||
include::cassandra:example$CQL/update_ttl_map.cql[]
|
||||
----
|
||||
|
||||
will only apply the TTL to the `{ 'color' : 'green' }` record, the rest
|
||||
|
|
@ -283,7 +283,7 @@ insert a set with:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/set.cql[]
|
||||
include::cassandra:example$CQL/set.cql[]
|
||||
----
|
||||
|
||||
Further, sets support:
|
||||
|
|
@ -293,27 +293,26 @@ already existing element is a no-op):
|
|||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/update_set.cql[]
|
||||
include::cassandra:example$CQL/update_set.cql[]
|
||||
----
|
||||
* Removing one or multiple elements (if an element doesn't exist,
|
||||
removing it is a no-op but no error is thrown):
|
||||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/delete_set.cql[]
|
||||
include::cassandra:example$CQL/delete_set.cql[]
|
||||
----
|
||||
|
||||
Lastly, for xref:cql/types.adoc#sets[sets], TTLs are only applied to newly inserted values.
|
||||
Lastly, for xref:cassandra:developing/cql/types.adoc#sets[sets], TTLs are only applied to newly inserted values.
|
||||
|
||||
=== Lists
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
As mentioned above and further discussed at the end of this section,
|
||||
lists have limitations and specific performance considerations that you
|
||||
should take into account before using them. In general, if you can use a
|
||||
xref:cql/types.adoc#sets[set] instead of list, always prefer a set.
|
||||
xref:cassandra:developing/cql/types.adoc#sets[set] instead of list, always prefer a set.
|
||||
====
|
||||
|
||||
A `list` is a (sorted) collection of non-unique values where
|
||||
|
|
@ -322,7 +321,7 @@ insert a list with:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/list.cql[]
|
||||
include::cassandra:example$CQL/list.cql[]
|
||||
----
|
||||
|
||||
Further, lists support:
|
||||
|
|
@ -331,7 +330,7 @@ Further, lists support:
|
|||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/update_list.cql[]
|
||||
include::cassandra:example$CQL/update_list.cql[]
|
||||
----
|
||||
|
||||
[WARNING]
|
||||
|
|
@ -348,7 +347,7 @@ will be thrown if the list does not have the position:
|
|||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/update_particular_list_element.cql[]
|
||||
include::cassandra:example$CQL/update_particular_list_element.cql[]
|
||||
----
|
||||
* Removing an element by its position in the list that has a pre-existing element for that position. An error
|
||||
will be thrown if the list does not have the position. Further, as the operation removes an
|
||||
|
|
@ -357,7 +356,7 @@ the position of all the following elements one forward:
|
|||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/delete_element_list.cql[]
|
||||
include::cassandra:example$CQL/delete_element_list.cql[]
|
||||
----
|
||||
|
||||
* Deleting _all_ the occurrences of particular values in the list (if a
|
||||
|
|
@ -366,7 +365,7 @@ ignored and no error is thrown):
|
|||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/delete_all_elements_list.cql[]
|
||||
include::cassandra:example$CQL/delete_all_elements_list.cql[]
|
||||
----
|
||||
|
||||
[WARNING]
|
||||
|
|
@ -378,7 +377,7 @@ run slowly and use more resources than usual updates (with the
|
|||
exclusion of conditional write that have their own cost).
|
||||
====
|
||||
|
||||
Lastly, for xref:cql/types.adoc#lists[lists], TTLs only apply to newly inserted values.
|
||||
Lastly, for xref:cassandra:developing/cql/types.adoc#lists[lists], TTLs only apply to newly inserted values.
|
||||
|
||||
[[vectors]]
|
||||
==== Working with vectors
|
||||
|
|
@ -389,7 +388,7 @@ You can define, insert and update a vector with:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/vector.cql[]
|
||||
include::cassandra:example$CQL/vector.cql[]
|
||||
----
|
||||
|
||||
Note that it isn't possible to change the individual values of a vector, and it isn't possible to select individual
|
||||
|
|
@ -406,7 +405,7 @@ referred to by its name:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/udt.bnf[]
|
||||
include::cassandra:example$BNF/udt.bnf[]
|
||||
----
|
||||
|
||||
=== Creating a UDT
|
||||
|
|
@ -416,7 +415,7 @@ defined by:
|
|||
|
||||
[source, bnf]
|
||||
----
|
||||
include::example$BNF/create_type.bnf[]
|
||||
include::cassandra:example$BNF/create_type.bnf[]
|
||||
----
|
||||
|
||||
A UDT has a name (used to declared columns of that type) and is a set of
|
||||
|
|
@ -425,7 +424,7 @@ collections or other UDT. For instance:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/udt.cql[]
|
||||
include::cassandra:example$CQL/udt.cql[]
|
||||
----
|
||||
|
||||
Things to keep in mind about UDTs:
|
||||
|
|
@ -447,16 +446,16 @@ UDT literal:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/udt_literal.bnf[]
|
||||
include::cassandra:example$BNF/udt_literal.bnf[]
|
||||
----
|
||||
|
||||
In other words, a UDT literal is like a xref:cql/types.adoc#maps[map]` literal but its
|
||||
In other words, a UDT literal is like a xref:cassandra:developing/cql/types.adoc#maps[map]` literal but its
|
||||
keys are the names of the fields of the type. For instance, one could
|
||||
insert into the table define in the previous section using:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/insert_udt.cql[]
|
||||
include::cassandra:example$CQL/insert_udt.cql[]
|
||||
----
|
||||
|
||||
To be valid, a UDT literal can only include fields defined by the
|
||||
|
|
@ -469,7 +468,7 @@ statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/alter_udt_statement.bnf[]
|
||||
include::cassandra:example$BNF/alter_udt_statement.bnf[]
|
||||
----
|
||||
If the type does not exist, the statement will return an error, unless `IF EXISTS` is used in which case the operation is a no-op.
|
||||
You can:
|
||||
|
|
@ -481,7 +480,7 @@ the addition. If the new field exists, the statement will return an error, unles
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/rename_udt_field.cql[]
|
||||
include::cassandra:example$CQL/rename_udt_field.cql[]
|
||||
----
|
||||
|
||||
=== Dropping a UDT
|
||||
|
|
@ -491,7 +490,7 @@ statement:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/drop_udt_statement.bnf[]
|
||||
include::cassandra:example$BNF/drop_udt_statement.bnf[]
|
||||
----
|
||||
|
||||
Dropping a type results in the immediate, irreversible removal of that
|
||||
|
|
@ -509,14 +508,14 @@ with anonymous fields. Tuple types and tuple literals are defined by:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/tuple.bnf[]
|
||||
include::cassandra:example$BNF/tuple.bnf[]
|
||||
----
|
||||
|
||||
and can be created:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/tuple.cql[]
|
||||
include::cassandra:example$CQL/tuple.cql[]
|
||||
----
|
||||
|
||||
Unlike other composed types, like collections and UDTs, a tuple is always
|
||||
|
|
@ -529,11 +528,10 @@ those values can be null but they need to be explicitly declared as so).
|
|||
== Custom Types
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
Custom types exists mostly for backward compatibility purposes and their
|
||||
usage is discouraged. Their usage is complex, not user friendly and the
|
||||
other provided types, particularly xref:cql/types.adoc#udts[user-defined types], should
|
||||
other provided types, particularly xref:cassandra:developing/cql/types.adoc#udts[user-defined types], should
|
||||
almost always be enough.
|
||||
====
|
||||
|
||||
|
|
@ -541,7 +539,7 @@ A custom type is defined by:
|
|||
|
||||
[source,bnf]
|
||||
----
|
||||
include::example$BNF/custom_type.bnf[]
|
||||
include::cassandra:example$BNF/custom_type.bnf[]
|
||||
----
|
||||
|
||||
A custom type is a `string` that contains the name of Java class that
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
= Logical Data Modeling
|
||||
|
||||
Now that you have defined your queries, you’re ready to begin designing
|
||||
Now that you have defined your queries, you're ready to begin designing
|
||||
Cassandra tables. First, create a logical model containing a table for
|
||||
each query, capturing entities and relationships from the conceptual
|
||||
model.
|
||||
|
||||
To name each table, you’ll identify the primary entity type for which
|
||||
To name each table, you'll identify the primary entity type for which
|
||||
you are querying and use that to start the entity name. If you are
|
||||
querying by attributes of other related entities, append those to the
|
||||
table name, separated with `_by_`. For example, `hotels_by_poi`.
|
||||
|
|
@ -24,7 +24,7 @@ the query. If any of these additional attributes are the same for every
|
|||
instance of the partition key, mark the column as static.
|
||||
|
||||
Now that was a pretty quick description of a fairly involved process, so
|
||||
it will be worthwhile to work through a detailed example. First, let’s
|
||||
it will be worthwhile to work through a detailed example. First, let's
|
||||
introduce a notation that you can use to represent logical models.
|
||||
|
||||
Several individuals within the Cassandra community have proposed
|
||||
|
|
@ -34,7 +34,7 @@ informative way to visualize the relationships between queries and
|
|||
tables in your designs. This figure shows the Chebotko notation for a
|
||||
logical data model.
|
||||
|
||||
image::data-modeling_chebotko_logical.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_chebotko_logical.png[image]
|
||||
|
||||
Each table is shown with its title and a list of columns. Primary key
|
||||
columns are identified via symbols such as *K* for partition key columns
|
||||
|
|
@ -46,31 +46,31 @@ table is designed to support.
|
|||
|
||||
The figure below shows a Chebotko logical data model for the queries
|
||||
involving hotels, points of interest, rooms, and amenities. One thing
|
||||
you'll notice immediately is that the Cassandra design doesn’t include
|
||||
you'll notice immediately is that the Cassandra design doesn't include
|
||||
dedicated tables for rooms or amenities, as you had in the relational
|
||||
design. This is because the workflow didn’t identify any queries
|
||||
design. This is because the workflow didn't identify any queries
|
||||
requiring this direct access.
|
||||
|
||||
image::data-modeling_hotel_logical.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_hotel_logical.png[image]
|
||||
|
||||
Let’s explore the details of each of these tables.
|
||||
Let's explore the details of each of these tables.
|
||||
|
||||
The first query Q1 is to find hotels near a point of interest, so you’ll
|
||||
The first query Q1 is to find hotels near a point of interest, so you'll
|
||||
call this table `hotels_by_poi`. Searching by a named point of interest
|
||||
is a clue that the point of interest should be a part of the primary
|
||||
key. Let’s reference the point of interest by name, because according to
|
||||
key. Let's reference the point of interest by name, because according to
|
||||
the workflow that is how users will start their search.
|
||||
|
||||
You’ll note that you certainly could have more than one hotel near a
|
||||
given point of interest, so you’ll need another component in the primary
|
||||
You'll note that you certainly could have more than one hotel near a
|
||||
given point of interest, so you'll need another component in the primary
|
||||
key in order to make sure you have a unique partition for each hotel. So
|
||||
you add the hotel key as a clustering column.
|
||||
|
||||
An important consideration in designing your table’s primary key is
|
||||
An important consideration in designing your table's primary key is
|
||||
making sure that it defines a unique data element. Otherwise you run the
|
||||
risk of accidentally overwriting data.
|
||||
|
||||
Now for the second query (Q2), you’ll need a table to get information
|
||||
Now for the second query (Q2), you'll need a table to get information
|
||||
about a specific hotel. One approach would have been to put all of the
|
||||
attributes of a hotel in the `hotels_by_poi` table, but you added only
|
||||
those attributes that were required by the application workflow.
|
||||
|
|
@ -81,10 +81,10 @@ and the application knows the unique identifiers of the hotels returned.
|
|||
When the user selects a hotel to view details, you can then use Q2,
|
||||
which is used to obtain details about the hotel. Because you already
|
||||
have the `hotel_id` from Q1, you use that as a reference to the hotel
|
||||
you’re looking for. Therefore the second table is just called `hotels`.
|
||||
you're looking for. Therefore the second table is just called `hotels`.
|
||||
|
||||
Another option would have been to store a set of `poi_names` in the
|
||||
hotels table. This is an equally valid approach. You’ll learn through
|
||||
hotels table. This is an equally valid approach. You'll learn through
|
||||
experience which approach is best for your application.
|
||||
|
||||
Q3 is just a reverse of Q1—looking for points of interest near a hotel,
|
||||
|
|
@ -93,14 +93,14 @@ need to access the details of each point of interest, as represented by
|
|||
the `pois_by_hotel` table. As previously, you add the point of interest
|
||||
name as a clustering key to guarantee uniqueness.
|
||||
|
||||
At this point, let’s now consider how to support query Q4 to help the
|
||||
At this point, let's now consider how to support query Q4 to help the
|
||||
user find available rooms at a selected hotel for the nights they are
|
||||
interested in staying. Note that this query involves both a start date
|
||||
and an end date. Because you’re querying over a range instead of a
|
||||
single date, you know that you’ll need to use the date as a clustering
|
||||
and an end date. Because you're querying over a range instead of a
|
||||
single date, you know that you'll need to use the date as a clustering
|
||||
key. Use the `hotel_id` as a primary key to group room data for each
|
||||
hotel on a single partition, which should help searches be super fast.
|
||||
Let’s call this the `available_rooms_by_hotel_date` table.
|
||||
Let's call this the `available_rooms_by_hotel_date` table.
|
||||
|
||||
To support searching over a range, use `clustering columns
|
||||
<clustering-columns>` to store attributes that you need to access in a
|
||||
|
|
@ -123,11 +123,11 @@ dates.
|
|||
== Reservation Logical Data Model
|
||||
|
||||
Now let's switch gears to look at the reservation queries. The figure
|
||||
shows a logical data model for reservations. You’ll notice that these
|
||||
shows a logical data model for reservations. You'll notice that these
|
||||
tables represent a denormalized design; the same data appears in
|
||||
multiple tables, with differing keys.
|
||||
|
||||
image::data-modeling_reservation_logical.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_reservation_logical.png[image]
|
||||
|
||||
In order to satisfy Q6, the `reservations_by_guest` table can be used to
|
||||
look up the reservation by guest name. You could envision query Q7 being
|
||||
|
|
@ -156,7 +156,7 @@ omitted from the example.
|
|||
== Patterns and Anti-Patterns
|
||||
|
||||
As with other types of software design, there are some well-known
|
||||
patterns and anti-patterns for data modeling in Cassandra. You’ve
|
||||
patterns and anti-patterns for data modeling in Cassandra. You've
|
||||
already used one of the most common patterns in this hotel model—the
|
||||
wide partition pattern.
|
||||
|
||||
|
|
@ -169,9 +169,9 @@ experiments.
|
|||
|
||||
The time series pattern is also useful for data other than measurements.
|
||||
Consider the example of a banking application. You could store each
|
||||
customer’s balance in a row, but that might lead to a lot of read and
|
||||
customer's balance in a row, but that might lead to a lot of read and
|
||||
write contention as various customers check their balance or make
|
||||
transactions. You’d probably be tempted to wrap a transaction around
|
||||
transactions. You'd probably be tempted to wrap a transaction around
|
||||
writes just to protect the balance from being updated in error. In
|
||||
contrast, a time series–style design would store each transaction as a
|
||||
timestamped row and leave the work of calculating the current balance to
|
||||
|
|
|
|||
|
|
@ -9,17 +9,17 @@ the basic types, collections, and user-defined types. You may identify
|
|||
additional user-defined types that can be created to simplify your
|
||||
design.
|
||||
|
||||
After you’ve assigned data types, you analyze the model by performing
|
||||
After you've assigned data types, you analyze the model by performing
|
||||
size calculations and testing out how the model works. You may make some
|
||||
adjustments based on your findings. Once again let's cover the data
|
||||
modeling process in more detail by working through an example.
|
||||
|
||||
Before getting started, let’s look at a few additions to the Chebotko
|
||||
Before getting started, let's look at a few additions to the Chebotko
|
||||
notation for physical data models. To draw physical models, you need to
|
||||
be able to add the typing information for each column. This figure shows
|
||||
the addition of a type for each column in a sample table.
|
||||
|
||||
image::data-modeling_chebotko_physical.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_chebotko_physical.png[image]
|
||||
|
||||
The figure includes a designation of the keyspace containing each table
|
||||
and visual cues for columns represented using collections and
|
||||
|
|
@ -30,15 +30,15 @@ concern.
|
|||
|
||||
== Hotel Physical Data Model
|
||||
|
||||
Now let’s get to work on the physical model. First, you need keyspaces
|
||||
Now let's get to work on the physical model. First, you need keyspaces
|
||||
to contain the tables. To keep the design relatively simple, create a
|
||||
`hotel` keyspace to contain tables for hotel and availability data, and
|
||||
a `reservation` keyspace to contain tables for reservation and guest
|
||||
data. In a real system, you might divide the tables across even more
|
||||
keyspaces in order to separate concerns.
|
||||
|
||||
For the `hotels` table, use Cassandra’s `text` type to represent the
|
||||
hotel’s `id`. For the address, create an `address` user defined type.
|
||||
For the `hotels` table, use Cassandra's `text` type to represent the
|
||||
hotel's `id`. For the address, create an `address` user defined type.
|
||||
Use the `text` type to represent the phone number, as there is
|
||||
considerable variance in the formatting of numbers between countries.
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ by short codes like "AZ123" or "NY229". This example uses these values
|
|||
for `hotel_ids`, while acknowledging they are not necessarily globally
|
||||
unique.
|
||||
|
||||
You’ll find that it’s often helpful to use unique IDs to uniquely
|
||||
You'll find that it's often helpful to use unique IDs to uniquely
|
||||
reference elements, and to use these `uuids` as references in tables
|
||||
representing other entities. This helps to minimize coupling between
|
||||
different entity types. This may prove especially effective if you are
|
||||
|
|
@ -61,7 +61,7 @@ As you work to create physical representations of various tables in the
|
|||
logical hotel data model, you use the same approach. The resulting
|
||||
design is shown in this figure:
|
||||
|
||||
image::data-modeling_hotel_physical.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_hotel_physical.png[image]
|
||||
|
||||
Note that the `address` type is also included in the design. It is
|
||||
designated with an asterisk to denote that it is a user-defined type,
|
||||
|
|
@ -74,19 +74,19 @@ type. This can reduce complexity in the design.
|
|||
|
||||
Remember that the scope of a UDT is the keyspace in which it is defined.
|
||||
To use `address` in the `reservation` keyspace defined below design,
|
||||
you’ll have to declare it again. This is just one of the many trade-offs
|
||||
you'll have to declare it again. This is just one of the many trade-offs
|
||||
you have to make in data model design.
|
||||
|
||||
== Reservation Physical Data Model
|
||||
|
||||
Now, let’s examine reservation tables in the design. Remember that the
|
||||
Now, let's examine reservation tables in the design. Remember that the
|
||||
logical model contained three denormalized tables to support queries for
|
||||
reservations by confirmation number, guest, and hotel and date. For the
|
||||
first iteration of your physical data model design, assume you're going
|
||||
to manage this denormalization manually. Note that this design could be
|
||||
revised to use Cassandra’s (experimental) materialized view feature.
|
||||
revised to use Cassandra's (experimental) materialized view feature.
|
||||
|
||||
image::data-modeling_reservation_physical.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_reservation_physical.png[image]
|
||||
|
||||
Note that the `address` type is reproduced in this keyspace and
|
||||
`guest_id` is modeled as a `uuid` type in all of the tables.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
= Defining Application Queries
|
||||
|
||||
Let’s try the query-first approach to start designing the data model for
|
||||
Let's try the query-first approach to start designing the data model for
|
||||
a hotel application. The user interface design for the application is
|
||||
often a great artifact to use to begin identifying queries. Let’s assume
|
||||
that you’ve talked with the project stakeholders and your UX designers
|
||||
often a great artifact to use to begin identifying queries. Let's assume
|
||||
that you've talked with the project stakeholders and your UX designers
|
||||
have produced user interface designs or wireframes for the key use
|
||||
cases. You’ll likely have a list of shopping queries like the following:
|
||||
cases. You'll likely have a list of shopping queries like the following:
|
||||
|
||||
* Q1. Find hotels near a given point of interest.
|
||||
* Q2. Find information about a given hotel, such as its name and
|
||||
|
|
@ -19,12 +19,12 @@ rather that explaining them in full. The queries listed here are
|
|||
numbered Q1, Q2, and so on, which is how they are referenced in diagrams
|
||||
throughout the example.
|
||||
|
||||
Now if the application is to be a success, you’ll certainly want
|
||||
Now if the application is to be a success, you'll certainly want
|
||||
customers to be able to book reservations at hotels. This includes steps
|
||||
such as selecting an available room and entering their guest
|
||||
information. So clearly you will also need some queries that address the
|
||||
reservation and guest entities from the conceptual data model. Even
|
||||
here, however, you’ll want to think not only from the customer
|
||||
here, however, you'll want to think not only from the customer
|
||||
perspective in terms of how the data is written, but also in terms of
|
||||
how the data will be queried by downstream use cases.
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ You natural tendency as might be to focus first on designing the tables
|
|||
to store reservation and guest records, and only then start thinking
|
||||
about the queries that would access them. You may have felt a similar
|
||||
tension already when discussing the shopping queries before, thinking
|
||||
“but where did the hotel and point of interest data come from?” Don’t
|
||||
“but where did the hotel and point of interest data come from?” Don't
|
||||
worry, you will see soon enough. Here are some queries that describe how
|
||||
users will access reservations:
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ users will access reservations:
|
|||
All of the queries are shown in the context of the workflow of the
|
||||
application in the figure below. Each box on the diagram represents a
|
||||
step in the application workflow, with arrows indicating the flows
|
||||
between steps and the associated query. If you’ve modeled the
|
||||
between steps and the associated query. If you've modeled the
|
||||
application well, each step of the workflow accomplishes a task that
|
||||
“unlocks” subsequent steps. For example, the “View hotels near POI” task
|
||||
helps the application learn about several hotels, including their unique
|
||||
|
|
@ -53,7 +53,7 @@ to obtain detailed description of the hotel. The act of booking a room
|
|||
creates a reservation record that may be accessed by the guest and hotel
|
||||
staff at a later time through various additional queries.
|
||||
|
||||
image::data-modeling_hotel_queries.png[image]
|
||||
image::cassandra:developing/data-modeling/data-modeling_hotel_queries.png[image]
|
||||
|
||||
_Material adapted from Cassandra, The Definitive Guide. Published by
|
||||
O'Reilly Media, Inc. Copyright © 2020 Jeff Carpenter, Eben Hewitt. All
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ image::data-modeling_hotel_relational.png[image]
|
|||
|
||||
== Design Differences Between RDBMS and Cassandra
|
||||
|
||||
Let’s take a minute to highlight some of the key differences in doing
|
||||
Let's take a minute to highlight some of the key differences in doing
|
||||
data modeling for Cassandra versus a relational database.
|
||||
|
||||
=== No joins
|
||||
|
||||
You cannot perform joins in Cassandra. If you have designed a data model
|
||||
and find that you need something like a join, you’ll have to either do
|
||||
and find that you need something like a join, you'll have to either do
|
||||
the work on the client side, or create a denormalized second table that
|
||||
represents the join results for you. This latter option is preferred in
|
||||
Cassandra data modeling. Performing joins on the client should be a very
|
||||
|
|
@ -45,8 +45,8 @@ normalization. This is not an advantage when working with Cassandra
|
|||
because it performs best when the data model is denormalized. It is
|
||||
often the case that companies end up denormalizing data in relational
|
||||
databases as well. There are two common reasons for this. One is
|
||||
performance. Companies simply can’t get the performance they need when
|
||||
they have to do so many joins on years’ worth of data, so they
|
||||
performance. Companies simply can't get the performance they need when
|
||||
they have to do so many joins on years' worth of data, so they
|
||||
denormalize along the lines of known queries. This ends up working, but
|
||||
goes against the grain of how relational databases are intended to be
|
||||
designed, and ultimately makes one question whether using a relational
|
||||
|
|
@ -57,17 +57,17 @@ a business document structure that requires retention. That is, you have
|
|||
an enclosing table that refers to a lot of external tables whose data
|
||||
could change over time, but you need to preserve the enclosing document
|
||||
as a snapshot in history. The common example here is with invoices. You
|
||||
already have customer and product tables, and you’d think that you could
|
||||
already have customer and product tables, and you'd think that you could
|
||||
just make an invoice that refers to those tables. But this should never
|
||||
be done in practice. Customer or price information could change, and
|
||||
then you would lose the integrity of the invoice document as it was on
|
||||
the invoice date, which could violate audits, reports, or laws, and
|
||||
cause other problems.
|
||||
|
||||
In the relational world, denormalization violates Codd’s normal forms,
|
||||
In the relational world, denormalization violates Codd's normal forms,
|
||||
and you try to avoid it. But in Cassandra, denormalization is, well,
|
||||
perfectly normal. It’s not required if your data model is simple. But
|
||||
don’t be afraid of it.
|
||||
perfectly normal. It's not required if your data model is simple. But
|
||||
don't be afraid of it.
|
||||
|
||||
Historically, denormalization in Cassandra has required designing and
|
||||
managing multiple tables using techniques described in this
|
||||
|
|
@ -83,7 +83,7 @@ Relational modeling, in simple terms, means that you start from the
|
|||
conceptual domain and then represent the nouns in the domain in tables.
|
||||
You then assign primary keys and foreign keys to model relationships.
|
||||
When you have a many-to-many relationship, you create the join tables
|
||||
that represent just those keys. The join tables don’t exist in the real
|
||||
that represent just those keys. The join tables don't exist in the real
|
||||
world, and are a necessary side effect of the way relational models
|
||||
work. After you have all your tables laid out, you can start writing
|
||||
queries that pull together disparate data using the relationships
|
||||
|
|
@ -92,7 +92,7 @@ secondary. It is assumed that you can always get the data you want as
|
|||
long as you have your tables modeled properly. Even if you have to use
|
||||
several complex subqueries or join statements, this is usually true.
|
||||
|
||||
By contrast, in Cassandra you don’t start with the data model; you start
|
||||
By contrast, in Cassandra you don't start with the data model; you start
|
||||
with the query model. Instead of modeling the data first and then
|
||||
writing queries, with Cassandra you model the queries and let the data
|
||||
be organized around them. Think of the most common query paths your
|
||||
|
|
@ -104,8 +104,8 @@ constraining on application design, not to mention database modeling.
|
|||
But it is perfectly reasonable to expect that you should think hard
|
||||
about the queries in your application, just as you would, presumably,
|
||||
think hard about your relational domain. You may get it wrong, and then
|
||||
you’ll have problems in either world. Or your query needs might change
|
||||
over time, and then you’ll have to work to update your data set. But
|
||||
you'll have problems in either world. Or your query needs might change
|
||||
over time, and then you'll have to work to update your data set. But
|
||||
this is no different from defining the wrong tables, or needing
|
||||
additional tables, in an RDBMS.
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ In a relational database, it is frequently transparent to the user how
|
|||
tables are stored on disk, and it is rare to hear of recommendations
|
||||
about data modeling based on how the RDBMS might store tables on disk.
|
||||
However, that is an important consideration in Cassandra. Because
|
||||
Cassandra tables are each stored in separate files on disk, it’s
|
||||
Cassandra tables are each stored in separate files on disk, it's
|
||||
important to keep related columns defined together in the same table.
|
||||
|
||||
A key goal that you will see as you begin creating data models in
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
= Evaluating and Refining Data Models
|
||||
:stem: latexmath
|
||||
|
||||
Once you’ve created a physical model, there are some steps you’ll want
|
||||
Once you've created a physical model, there are some steps you'll want
|
||||
to take to evaluate and refine table designs to help ensure optimal
|
||||
performance.
|
||||
|
||||
|
|
@ -10,8 +10,8 @@ performance.
|
|||
The first thing that you want to look for is whether your tables will
|
||||
have partitions that will be overly large, or to put it another way, too
|
||||
wide. Partition size is measured by the number of cells (values) that
|
||||
are stored in the partition. Cassandra’s hard limit is 2 billion cells
|
||||
per partition, but you’ll likely run into performance issues before
|
||||
are stored in the partition. Cassandra's hard limit is 2 billion cells
|
||||
per partition, but you'll likely run into performance issues before
|
||||
reaching that limit.
|
||||
|
||||
In order to calculate the size of partitions, use the following formula:
|
||||
|
|
@ -35,7 +35,7 @@ potential to get too large. Two billion values sounds like a lot, but in
|
|||
a sensor system where tens or hundreds of values are measured every
|
||||
millisecond, the number of values starts to add up pretty fast.
|
||||
|
||||
Let’s take a look at one of the tables to analyze the partition size.
|
||||
Let's take a look at one of the tables to analyze the partition size.
|
||||
Because it has a wide partition design with one partition per hotel,
|
||||
look at the `available_rooms_by_hotel_date` table. The table has four
|
||||
columns total (N~c~ = 4), including three primary key columns (N~pk~ =
|
||||
|
|
@ -65,7 +65,7 @@ per partition is as follows:
|
|||
|
||||
This relatively small number of rows per partition is not going to get
|
||||
you in too much trouble, but if you start storing more dates of
|
||||
inventory, or don’t manage the size of the inventory well using TTL, you
|
||||
inventory, or don't manage the size of the inventory well using TTL, you
|
||||
could start having issues. You still might want to look at breaking up
|
||||
this large partition, which you'll see how to do shortly.
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ of a partition:
|
|||
++++
|
||||
|
||||
This is a bit more complex than the previous formula, but let's break it
|
||||
down a bit at a time. Let’s take a look at the notation first:
|
||||
down a bit at a time. Let's take a look at the notation first:
|
||||
|
||||
* In this formula, c~k~ refers to partition key columns, c~s~ to static
|
||||
columns, c~r~ to regular columns, and c~c~ to clustering columns.
|
||||
|
|
@ -144,7 +144,7 @@ disk, but is accurate enough to be quite useful. Remembering that the
|
|||
partition must be able to fit on a single node, it looks like the table
|
||||
design will not put a lot of strain on disk storage.
|
||||
|
||||
Cassandra’s storage engine was re-implemented for the 3.0 release,
|
||||
Cassandra's storage engine was re-implemented for the 3.0 release,
|
||||
including a new format for SSTable files. The previous format stored a
|
||||
separate copy of the clustering columns as part of the record for each
|
||||
cell. The newer format eliminates this duplication, which reduces the
|
||||
|
|
@ -152,7 +152,7 @@ size of stored data and simplifies the formula for computing that size.
|
|||
|
||||
Keep in mind also that this estimate only counts a single replica of
|
||||
data. You will need to multiply the value obtained here by the number of
|
||||
partitions and the number of replicas specified by the keyspace’s
|
||||
partitions and the number of replicas specified by the keyspace's
|
||||
replication strategy in order to determine the total required total
|
||||
capacity for each table. This will come in handy when you plan your
|
||||
cluster.
|
||||
|
|
@ -163,7 +163,7 @@ As discussed previously, the goal is to design tables that can provide
|
|||
the data you need with queries that touch a single partition, or failing
|
||||
that, the minimum possible number of partitions. However, as shown in
|
||||
the examples, it is quite possible to design wide partition-style tables
|
||||
that approach Cassandra’s built-in limits. Performing sizing analysis on
|
||||
that approach Cassandra's built-in limits. Performing sizing analysis on
|
||||
tables may reveal partitions that are potentially too large, either in
|
||||
number of values, size on disk, or both.
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ data for consecutive days will likely be on separate nodes.
|
|||
Another technique known as *bucketing* is often used to break the data
|
||||
into moderate-size partitions. For example, you could bucketize the
|
||||
`available_rooms_by_hotel_date` table by adding a `month` column to the
|
||||
partition key, perhaps represented as an integer. The comparision with
|
||||
partition key, perhaps represented as an integer. The comparison with
|
||||
the original design is shown in the figure below. While the `month`
|
||||
column is partially duplicative of the `date`, it provides a nice way of
|
||||
grouping related data in a partition that will not get too large.
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
= Defining Database Schema
|
||||
|
||||
Once you have finished evaluating and refining the physical model,
|
||||
you’re ready to implement the schema in CQL. Here is the schema for the
|
||||
`hotel` keyspace, using CQL’s comment feature to document the query
|
||||
you're ready to implement the schema in CQL. Here is the schema for the
|
||||
`hotel` keyspace, using CQL's comment feature to document the query
|
||||
pattern supported by each table:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
CREATE KEYSPACE hotel WITH replication =
|
||||
{‘class’: ‘SimpleStrategy’, ‘replication_factor’ : 3};
|
||||
{'class': 'SimpleStrategy', 'replication_factor' : 3};
|
||||
|
||||
CREATE TYPE hotel.address (
|
||||
street text,
|
||||
|
|
@ -24,7 +24,7 @@ CREATE TABLE hotel.hotels_by_poi (
|
|||
phone text,
|
||||
address frozen<address>,
|
||||
PRIMARY KEY ((poi_name), hotel_id) )
|
||||
WITH comment = ‘Q1. Find hotels near given poi’
|
||||
WITH comment = 'Q1. Find hotels near given poi'
|
||||
AND CLUSTERING ORDER BY (hotel_id ASC) ;
|
||||
|
||||
CREATE TABLE hotel.hotels (
|
||||
|
|
@ -33,14 +33,14 @@ CREATE TABLE hotel.hotels (
|
|||
phone text,
|
||||
address frozen<address>,
|
||||
pois set<text> )
|
||||
WITH comment = ‘Q2. Find information about a hotel’;
|
||||
WITH comment = 'Q2. Find information about a hotel';
|
||||
|
||||
CREATE TABLE hotel.pois_by_hotel (
|
||||
poi_name text,
|
||||
hotel_id text,
|
||||
description text,
|
||||
PRIMARY KEY ((hotel_id), poi_name) )
|
||||
WITH comment = Q3. Find pois near a hotel’;
|
||||
WITH comment = Q3. Find pois near a hotel';
|
||||
|
||||
CREATE TABLE hotel.available_rooms_by_hotel_date (
|
||||
hotel_id text,
|
||||
|
|
@ -48,7 +48,7 @@ CREATE TABLE hotel.available_rooms_by_hotel_date (
|
|||
room_number smallint,
|
||||
is_available boolean,
|
||||
PRIMARY KEY ((hotel_id), date, room_number) )
|
||||
WITH comment = ‘Q4. Find available rooms by hotel date’;
|
||||
WITH comment = 'Q4. Find available rooms by hotel date';
|
||||
|
||||
CREATE TABLE hotel.amenities_by_room (
|
||||
hotel_id text,
|
||||
|
|
@ -56,7 +56,7 @@ CREATE TABLE hotel.amenities_by_room (
|
|||
amenity_name text,
|
||||
description text,
|
||||
PRIMARY KEY ((hotel_id, room_number), amenity_name) )
|
||||
WITH comment = ‘Q5. Find amenities for a room’;
|
||||
WITH comment = 'Q5. Find amenities for a room';
|
||||
----
|
||||
|
||||
Notice that the elements of the partition key are surrounded with
|
||||
|
|
@ -68,8 +68,8 @@ Similarly, here is the schema for the `reservation` keyspace:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
CREATE KEYSPACE reservation WITH replication = {‘class’:
|
||||
‘SimpleStrategy’, ‘replication_factor’ : 3};
|
||||
CREATE KEYSPACE reservation WITH replication = {'class':
|
||||
'SimpleStrategy', 'replication_factor' : 3};
|
||||
|
||||
CREATE TYPE reservation.address (
|
||||
street text,
|
||||
|
|
@ -86,7 +86,7 @@ CREATE TABLE reservation.reservations_by_confirmation (
|
|||
room_number smallint,
|
||||
guest_id uuid,
|
||||
PRIMARY KEY (confirm_number) )
|
||||
WITH comment = ‘Q6. Find reservations by confirmation number’;
|
||||
WITH comment = 'Q6. Find reservations by confirmation number';
|
||||
|
||||
CREATE TABLE reservation.reservations_by_hotel_date (
|
||||
hotel_id text,
|
||||
|
|
@ -96,7 +96,7 @@ CREATE TABLE reservation.reservations_by_hotel_date (
|
|||
confirm_number text,
|
||||
guest_id uuid,
|
||||
PRIMARY KEY ((hotel_id, start_date), room_number) )
|
||||
WITH comment = ‘Q7. Find reservations by hotel and date’;
|
||||
WITH comment = 'Q7. Find reservations by hotel and date';
|
||||
|
||||
CREATE TABLE reservation.reservations_by_guest (
|
||||
guest_last_name text,
|
||||
|
|
@ -107,7 +107,7 @@ CREATE TABLE reservation.reservations_by_guest (
|
|||
confirm_number text,
|
||||
guest_id uuid,
|
||||
PRIMARY KEY ((guest_last_name), hotel_id) )
|
||||
WITH comment = ‘Q8. Find reservations by guest name’;
|
||||
WITH comment = 'Q8. Find reservations by guest name';
|
||||
|
||||
CREATE TABLE reservation.guests (
|
||||
guest_id uuid PRIMARY KEY,
|
||||
|
|
@ -119,7 +119,7 @@ CREATE TABLE reservation.guests (
|
|||
addresses map<text,
|
||||
frozen<address>,
|
||||
confirm_number text )
|
||||
WITH comment = ‘Q9. Find guest by ID’;
|
||||
WITH comment = 'Q9. Find guest by ID';
|
||||
----
|
||||
|
||||
You now have a complete Cassandra schema for storing data for a hotel
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
= Data Modeling
|
||||
|
||||
* xref:data-modeling/intro.adoc[Introduction]
|
||||
* xref:data-modeling/data-modeling_rdbms.adoc[RDBMS]
|
||||
* xref:data-modeling/data-modeling_conceptual.adoc[Conceptual]
|
||||
* xref:data-modeling/data-modeling_logical.adoc[Logical]
|
||||
* xref:data-modeling/data-modeling_physical.adoc[Physical]
|
||||
* xref:data-modeling/data-modeling_schema.adoc[Schema]
|
||||
* xref:data-modeling/data-modeling_queries.adoc[Queries]
|
||||
* xref:data-modeling/data-modeling_refining.adoc[Refining]
|
||||
* xref:data-modeling/data-modeling_tools.adoc[Tools]
|
||||
* xref:cassandra:developing/data-modeling/intro.adoc[Introduction]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_rdbms.adoc[RDBMS]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_conceptual.adoc[Conceptual]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_logical.adoc[Logical]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_physical.adoc[Physical]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_schema.adoc[Schema]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_queries.adoc[Queries]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_refining.adoc[Refining]
|
||||
* xref:cassandra:developing/data-modeling/data-modeling_tools.adoc[Tools]
|
||||
|
|
|
|||
|
|
@ -149,35 +149,35 @@ not all data attributes are needed for Q1 the data model would only
|
|||
consist of `id` ( for partition key), magazine name and publication
|
||||
frequency as shown in Figure 1.
|
||||
|
||||
.Data Model for Q1
|
||||
image::Figure_1_data_model.jpg[image]
|
||||
|
||||
Figure 1. Data Model for Q1
|
||||
|
||||
Another query (Q2) is to list all the magazine names by publisher. For
|
||||
Q2 the data model would consist of an additional attribute `publisher`
|
||||
for the partition key. The `id` would become the clustering key for
|
||||
sorting within a partition. Data model for Q2 is illustrated in Figure
|
||||
2.
|
||||
|
||||
.Data Model for Q2
|
||||
image::Figure_2_data_model.jpg[image]
|
||||
|
||||
Figure 2. Data Model for Q2
|
||||
|
||||
== Designing Schema
|
||||
|
||||
After the conceptual data model has been created a schema may be
|
||||
designed for a query. For Q1 the following schema may be used.
|
||||
|
||||
....
|
||||
[source, cql]
|
||||
----
|
||||
CREATE TABLE magazine_name (id int PRIMARY KEY, name text, publicationFrequency text)
|
||||
....
|
||||
----
|
||||
|
||||
For Q2 the schema definition would include a clustering key for sorting.
|
||||
|
||||
....
|
||||
CREATE TABLE magazine_publisher (publisher text,id int,name text, publicationFrequency text,
|
||||
[source, cql]
|
||||
----
|
||||
CREATE TABLE magazine_publisher (publisher text,id int,name text, publicationFrequency text,
|
||||
PRIMARY KEY (publisher, id)) WITH CLUSTERING ORDER BY (id DESC)
|
||||
....
|
||||
----
|
||||
|
||||
== Data Model Analysis
|
||||
|
||||
|
|
@ -207,10 +207,10 @@ minimum.
|
|||
== Using Materialized Views
|
||||
|
||||
[WARNING]
|
||||
.Warning
|
||||
====
|
||||
Materialized views (MVs) are experimental in the latest (4.0) release.
|
||||
Materialized views (MVs) are experimental as of the 4.0 release.
|
||||
====
|
||||
|
||||
Materialized views (MVs) could be used to implement multiple queries
|
||||
for a single table. A materialized view is a table built from data from
|
||||
another table, the base table, with new primary key and new properties.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
= Developing
|
||||
|
||||
* xref:cassandra:developing/data-modeling/index.adoc[Data Modeling]
|
||||
* xref:cassandra:developing/cql/index.adoc[CQL]
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
This section covers how to get started using Apache Cassandra and should
|
||||
be the first thing to read if you are new to Cassandra.
|
||||
|
||||
* xref:installing/installing.adoc[Installing Cassandra]: Installation instructions plus information on choosing a method.
|
||||
* xref:installing/installing.adoc[Installing Cassandra]: Installation instructions plus information on choosing a method.
|
||||
** [ xref:installing/installing.adoc#installing-the-docker-image[Docker] ]
|
||||
[ xref:installing/installing.adoc#installing-the-binary-tarball[tarball] ]
|
||||
[ xref:installing/installing.adoc#installing-the-debian-packages[Debian] ]
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ getting started. As an example if Java 11 is used, the run output should
|
|||
include similar to the following output snippet:
|
||||
|
||||
....
|
||||
INFO [main] 2019-07-31 21:18:16,862 CassandraDaemon.java:480 - Hostname: ip-172-30-3-
|
||||
INFO [main] 2019-07-31 21:18:16,862 CassandraDaemon.java:480 - Hostname: ip-172-30-3-
|
||||
146.ec2.internal:7000:7001
|
||||
INFO [main] 2019-07-31 21:18:16,862 CassandraDaemon.java:487 - JVM vendor/version: OpenJDK
|
||||
INFO [main] 2019-07-31 21:18:16,862 CassandraDaemon.java:487 - JVM vendor/version: OpenJDK
|
||||
64-Bit Server VM/11.0.3
|
||||
INFO [main] 2019-07-31 21:18:16,863 CassandraDaemon.java:488 - Heap size:
|
||||
INFO [main] 2019-07-31 21:18:16,863 CassandraDaemon.java:488 - Heap size:
|
||||
1004.000MiB/1004.000MiB
|
||||
....
|
||||
|
||||
|
|
@ -110,22 +110,22 @@ The following output indicates a single node Cassandra 4.0 cluster has
|
|||
started.
|
||||
|
||||
....
|
||||
INFO [main] 2019-07-31 21:18:19,687 InboundConnectionInitiator.java:130 - Listening on
|
||||
INFO [main] 2019-07-31 21:18:19,687 InboundConnectionInitiator.java:130 - Listening on
|
||||
address: (127.0.0.1:7000), nic: lo, encryption: enabled (openssl)
|
||||
...
|
||||
...
|
||||
INFO [main] 2019-07-31 21:18:19,850 StorageService.java:512 - Unable to gossip with any
|
||||
INFO [main] 2019-07-31 21:18:19,850 StorageService.java:512 - Unable to gossip with any
|
||||
peers but continuing anyway since node is in its own seed list
|
||||
INFO [main] 2019-07-31 21:18:19,864 StorageService.java:695 - Loading persisted ring state
|
||||
INFO [main] 2019-07-31 21:18:19,865 StorageService.java:814 - Starting up server gossip
|
||||
INFO [main] 2019-07-31 21:18:20,088 BufferPool.java:216 - Global buffer pool is enabled,
|
||||
INFO [main] 2019-07-31 21:18:20,088 BufferPool.java:216 - Global buffer pool is enabled,
|
||||
when pool is exhausted (max is 251.000MiB) it will allocate on heap
|
||||
INFO [main] 2019-07-31 21:18:20,110 StorageService.java:875 - This node will not auto
|
||||
INFO [main] 2019-07-31 21:18:20,110 StorageService.java:875 - This node will not auto
|
||||
bootstrap because it is configured to be a seed node.
|
||||
...
|
||||
...
|
||||
INFO [main] 2019-07-31 21:18:20,809 StorageService.java:1507 - JOINING: Finish joining ring
|
||||
INFO [main] 2019-07-31 21:18:20,921 StorageService.java:2508 - Node 127.0.0.1:7000 state
|
||||
INFO [main] 2019-07-31 21:18:20,921 StorageService.java:2508 - Node 127.0.0.1:7000 state
|
||||
jump to NORMAL
|
||||
....
|
||||
|
||||
|
|
@ -190,13 +190,13 @@ message gets output.
|
|||
Last login: Wed Jul 31 20:47:26 2019 from 75.155.255.51
|
||||
$ echo $JAVA_HOME
|
||||
/usr/lib/jvm/java-1.8.0-openjdk
|
||||
$ cassandra
|
||||
$ cassandra
|
||||
...
|
||||
...
|
||||
Error: A JNI error has occurred, please check your installation and try again
|
||||
Exception in thread "main" java.lang.UnsupportedClassVersionError:
|
||||
org/apache/cassandra/service/CassandraDaemon has been compiled by a more recent version of
|
||||
the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes
|
||||
Exception in thread "main" java.lang.UnsupportedClassVersionError:
|
||||
org/apache/cassandra/service/CassandraDaemon has been compiled by a more recent version of
|
||||
the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes
|
||||
class file versions up to 52.0
|
||||
at java.lang.ClassLoader.defineClass1(Native Method)
|
||||
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
= Inserting and querying
|
||||
|
||||
The API for Cassandra is xref:cql/ddl.adoc[`CQL`, the Cassandra Query Language]. To
|
||||
The API for Cassandra is xref:cassandra:developing/cql/ddl.adoc[`CQL`, the Cassandra Query Language]. To
|
||||
use CQL, you will need to connect to the cluster, using either:
|
||||
|
||||
* `cqlsh`, a shell for CQL
|
||||
|
|
@ -16,11 +16,11 @@ single node specified on the command line. For example:
|
|||
|
||||
[source, shell]
|
||||
----
|
||||
include::example$BASH/cqlsh_localhost.sh[]
|
||||
include::cassandra:example$BASH/cqlsh_localhost.sh[]
|
||||
----
|
||||
[source, cql]
|
||||
----
|
||||
include::example$RESULTS/cqlsh_localhost.result[]
|
||||
include::cassandra:example$RESULTS/cqlsh_localhost.result[]
|
||||
----
|
||||
If the command is used without specifying a node, `localhost` is the default. See the xref:tools/cqlsh.adoc[`cqlsh` section] for full documentation.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,41 +1,36 @@
|
|||
= Installing Cassandra
|
||||
:tabs:
|
||||
|
||||
These are the instructions for deploying the supported releases of
|
||||
Apache Cassandra on Linux servers.
|
||||
Apache Cassandra can be installed on a number of Linux distributions:
|
||||
|
||||
Cassandra runs on a wide array of Linux distributions including (but not
|
||||
limited to):
|
||||
* AlmaLinux
|
||||
* Amazon Linux Amazon Machine Images (AMIs)
|
||||
* Debian
|
||||
* RedHat Enterprise Linux (RHEL)
|
||||
* SUSE Enterprise Linux
|
||||
* Ubuntu
|
||||
|
||||
* Ubuntu, most notably LTS releases 16.04 to 18.04
|
||||
* CentOS & RedHat Enterprise Linux (RHEL) including 6.6 to 7.7
|
||||
* Amazon Linux AMIs including 2016.09 through to Linux 2
|
||||
* Debian versions 8 & 9
|
||||
* SUSE Enterprise Linux 12
|
||||
|
||||
This is not an exhaustive list of operating system platforms, nor is it
|
||||
prescriptive. However, users will be well-advised to conduct exhaustive
|
||||
tests of their own particularly for less-popular distributions of Linux.
|
||||
Deploying on older versions is not recommended unless you have previous
|
||||
experience with the older distribution in a production environment.
|
||||
This is not an exhaustive list of operating system platforms, nor is it prescriptive.
|
||||
However, users are well-advised to conduct exhaustive tests if using a less-popular distribution of Linux.
|
||||
Deploying on older Linux versions is not recommended unless you have previous experience with the older distribution in a production environment.
|
||||
|
||||
== Prerequisites
|
||||
|
||||
* Install the latest version of Java 8 or Java 11, either the
|
||||
http://www.oracle.com/technetwork/java/javase/downloads/index.html[Oracle
|
||||
Java Standard Edition 8] / http://www.oracle.com/technetwork/java/javase/downloads/index.html[Oracle Java Standard Edition 11 (Long Term Support)]
|
||||
or http://openjdk.java.net/[OpenJDK 8] / http://openjdk.java.net/[OpenJDK 11]. To
|
||||
verify that you have the correct version of java installed, type
|
||||
`java -version`.
|
||||
* *NOTE*: Experimental support for Java 11 was added in Cassandra {40_version}
|
||||
(https://issues.apache.org/jira/browse/CASSANDRA-9608[CASSANDRA-9608]).
|
||||
Full support is effective Cassandra 4.0.2 version (https://issues.apache.org/jira/browse/CASSANDRA-16894[CASSANDRA-16894])
|
||||
For more information, see
|
||||
https://github.com/apache/cassandra/blob/trunk/NEWS.txt[NEWS.txt].
|
||||
* For using cqlsh, the latest version of
|
||||
Python 3.6+ or Python 2.7 (support deprecated). To verify
|
||||
that you have the correct version of Python installed, type
|
||||
`python --version`.
|
||||
* Install the latest version of Java 11 or Java 17, from one of the following locations:
|
||||
** https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html[Oracle Java Standard Edition 11 Archived Version]
|
||||
** https://www.oracle.com/java/technologies/downloads/#java17[Oracle Java Standard Edition 17]
|
||||
** https://jdk.java.net/archive/[OpenJDK 11]
|
||||
** https://jdk.java.net/archive/[OpenJDK 17]
|
||||
|
||||
include::cassandra:partial$java_version.adoc[]
|
||||
|
||||
* To use the CQL shell `cqlsh`, install the latest version of Python 3.6+.
|
||||
|
||||
To verify that you have the correct version of Python installed, type `python --version`.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Support for Python 2.7 is deprecated.
|
||||
====
|
||||
|
||||
== Choosing an installation method
|
||||
|
||||
|
|
@ -45,88 +40,79 @@ There are three methods of installing Cassandra that are common:
|
|||
* Tarball binary file
|
||||
* Package installation (RPM, YUM)
|
||||
|
||||
If you are a current Docker user, installing a Docker image is simple.
|
||||
You'll need to install Docker Desktop for Mac, Docker Desktop for Windows,
|
||||
or have `docker` installed on Linux.
|
||||
Pull the appropriate image and then start Cassandra with a run command.
|
||||
If you are a current Docker user, installing a Docker image is simple.
|
||||
You'll need to install Docker Desktop for Mac, Docker Desktop for Windows, or have `docker` installed on Linux.
|
||||
Pull the appropriate image from the Docker Hub and start Cassandra with a `docker run` command.
|
||||
|
||||
For most users, installing the binary tarball is also a simple choice.
|
||||
The tarball unpacks all its contents into a single location with
|
||||
binaries and configuration files located in their own subdirectories.
|
||||
The most obvious attribute of the tarball installation is it does not
|
||||
require `root` permissions and can be installed on any Linux
|
||||
For many users, installing the binary tarball is also a simple choice.
|
||||
The tarball unpacks all its contents into a single location with binaries and configuration files located in their own subdirectories.
|
||||
The most obvious advantage of a tarball installation is that it does not require `root` permissions and can be installed on any Linux
|
||||
distribution.
|
||||
|
||||
Packaged installations require `root` permissions, and are most appropriate for
|
||||
production installs.
|
||||
Install the RPM build on CentOS and RHEL-based distributions if you want to
|
||||
install Cassandra using YUM.
|
||||
Install the Debian build on Ubuntu and other Debian-based
|
||||
distributions if you want to install Cassandra using APT.
|
||||
Note that both the YUM and APT methods required `root` permissions and
|
||||
will install the binaries and configuration files as the `cassandra` OS user.
|
||||
Packaged installations require `root` permissions, and are most appropriate for production installs.
|
||||
Install the RPM build on CentOS and RHEL-based distributions if you want to install Cassandra using YUM.
|
||||
Install the Debian build on Ubuntu and other Debian-based distributions if you want to install Cassandra using APT.
|
||||
|
||||
== Installing the docker image
|
||||
[WARNING]
|
||||
====
|
||||
Note that both the YUM and APT methods required `root` permissions and will install the binaries and configuration files as the `cassandra` OS user.
|
||||
====
|
||||
|
||||
== Install with Docker
|
||||
|
||||
[arabic, start=1]
|
||||
. Pull the docker image. For the latest image, use:
|
||||
|
||||
+
|
||||
[source, shell]
|
||||
----
|
||||
include::example$BASH/docker_pull.sh[]
|
||||
include::cassandra:example$BASH/docker_pull.sh[]
|
||||
----
|
||||
|
||||
This `docker pull` command will get the latest version of the 'Docker Official'
|
||||
+
|
||||
This `docker pull` command will get the latest version of the official Docker
|
||||
Apache Cassandra image available from the https://hub.docker.com/_/cassandra[Dockerhub].
|
||||
|
||||
[arabic, start=2]
|
||||
. Start Cassandra with a `docker run` command:
|
||||
|
||||
+
|
||||
[source, shell]
|
||||
----
|
||||
include::example$BASH/docker_run.sh[]
|
||||
include::cassandra:example$BASH/docker_run.sh[]
|
||||
----
|
||||
|
||||
+
|
||||
The `--name` option will be the name of the Cassandra cluster created.
|
||||
|
||||
[arabic, start=3]
|
||||
This example uses the name `cass_cluster`.
|
||||
. Start the CQL shell, `cqlsh` to interact with the Cassandra node created:
|
||||
|
||||
+
|
||||
[source, shell]
|
||||
----
|
||||
include::example$BASH/docker_cqlsh.sh[]
|
||||
include::cassandra:example$BASH/docker_cqlsh.sh[]
|
||||
----
|
||||
== Installing the binary tarball
|
||||
|
||||
include::partial$java_version.adoc[]
|
||||
== Install tarball file
|
||||
|
||||
[arabic, start=2]
|
||||
. Download the binary tarball from one of the mirrors on the
|
||||
{cass_url}download/[Apache Cassandra Download] site.
|
||||
include::cassandra:partial$java_version.adoc[]
|
||||
|
||||
. Download the binary tarball from one of the mirrors on the {cass_url}download/[Apache Cassandra Download] site.
|
||||
For example, to download Cassandra {40_version}:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/curl_install.sh[]
|
||||
include::cassandra:example$BASH/curl_install.sh[]
|
||||
----
|
||||
|
||||
NOTE: The mirrors only host the latest versions of each major supported
|
||||
release. To download an earlier version of Cassandra, visit the
|
||||
http://archive.apache.org/dist/cassandra/[Apache Archives].
|
||||
|
||||
[arabic, start=3]
|
||||
. OPTIONAL: Verify the integrity of the downloaded tarball using one of
|
||||
the methods https://www.apache.org/dyn/closer.cgi#verify[here]. For
|
||||
example, to verify the hash of the downloaded file using GPG:
|
||||
|
||||
[{tabs}]
|
||||
+
|
||||
[NOTE]
|
||||
====
|
||||
The mirrors only host the latest versions of each major supported release.
|
||||
To download an earlier version of Cassandra, visit the http://archive.apache.org/dist/cassandra/[Apache Archives].
|
||||
====
|
||||
. OPTIONAL: Verify the integrity of the downloaded tarball using one of the methods https://www.apache.org/dyn/closer.cgi#verify[here].
|
||||
For example, to verify the hash of the downloaded file using GPG:
|
||||
+
|
||||
[tabs]
|
||||
====
|
||||
Command::
|
||||
+
|
||||
--
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/verify_gpg.sh[]
|
||||
include::cassandra:example$BASH/verify_gpg.sh[]
|
||||
----
|
||||
--
|
||||
|
||||
|
|
@ -135,21 +121,21 @@ Result::
|
|||
--
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/verify_gpg.result[]
|
||||
include::cassandra:example$RESULTS/verify_gpg.result[]
|
||||
----
|
||||
--
|
||||
====
|
||||
|
||||
+
|
||||
Compare the signature with the SHA256 file from the Downloads site:
|
||||
|
||||
[{tabs}]
|
||||
+
|
||||
[tabs]
|
||||
====
|
||||
Command::
|
||||
+
|
||||
--
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/curl_verify_sha.sh[]
|
||||
include::cassandra:example$BASH/curl_verify_sha.sh[]
|
||||
----
|
||||
--
|
||||
|
||||
|
|
@ -162,100 +148,65 @@ Result::
|
|||
----
|
||||
--
|
||||
====
|
||||
|
||||
[arabic, start=4]
|
||||
. Unpack the tarball:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/tarball.sh[]
|
||||
include::cassandra:example$BASH/tarball.sh[]
|
||||
----
|
||||
|
||||
+
|
||||
The files will be extracted to the `apache-cassandra-4.0.0/` directory.
|
||||
This is the tarball installation location.
|
||||
|
||||
[arabic, start=5]
|
||||
. Located in the tarball installation location are the directories for
|
||||
the scripts, binaries, utilities, configuration, data and log files:
|
||||
|
||||
. Located in the tarball installation location are the directories for the scripts, binaries, utilities, configuration, data and log files:
|
||||
+
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$TEXT/tarball_install_dirs.txt[]
|
||||
include::cassandra:example$TEXT/tarball_install_dirs.txt[]
|
||||
----
|
||||
<1> location of the commands to run cassandra, cqlsh, nodetool, and SSTable tools
|
||||
<2> location of cassandra.yaml and other configuration files
|
||||
<3> location of the commit logs, hints, and SSTables
|
||||
<4> location of system and debug logs
|
||||
<5>location of cassandra-stress tool
|
||||
|
||||
For information on how to configure your installation, see
|
||||
{cass_url}doc/latest/getting-started/configuring.html[Configuring
|
||||
Cassandra].
|
||||
|
||||
[arabic, start=6]
|
||||
+
|
||||
. Start Cassandra:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/start_tarball.sh[]
|
||||
include::cassandra:example$BASH/start_tarball.sh[]
|
||||
----
|
||||
+
|
||||
[NOTE]
|
||||
====
|
||||
This will run Cassandra as the authenticated Linux user.
|
||||
====
|
||||
+
|
||||
include::cassandra:partial$tail_syslog.adoc[]
|
||||
+
|
||||
include::cassandra:partial$nodetool_and_cqlsh.adoc[]
|
||||
|
||||
NOTE: This will run Cassandra as the authenticated Linux user.
|
||||
== Install as Debian package
|
||||
|
||||
include::partial$tail_syslog.adoc[]
|
||||
You can monitor the progress of the startup with:
|
||||
include::cassandra:partial$java_version.adoc[]
|
||||
|
||||
[{tabs}]
|
||||
. Add the Apache repository of Cassandra to the file `cassandra.sources.list`.
|
||||
+
|
||||
include::cassandra:partial$package_versions.adoc[]
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::cassandra:example$BASH/get_deb_package.sh[]
|
||||
----
|
||||
. Add the Apache Cassandra repository keys to the list of trusted keys on the server:
|
||||
+
|
||||
[tabs]
|
||||
====
|
||||
Command::
|
||||
+
|
||||
--
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/tail_syslog.sh[]
|
||||
----
|
||||
--
|
||||
|
||||
Result::
|
||||
+
|
||||
--
|
||||
Cassandra is ready when you see an entry like this in the `system.log`:
|
||||
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/tail_syslog.result[]
|
||||
----
|
||||
--
|
||||
====
|
||||
|
||||
include::partial$nodetool_and_cqlsh.adoc[]
|
||||
|
||||
== Installing the Debian packages
|
||||
|
||||
include::partial$java_version.adoc[]
|
||||
|
||||
[arabic, start=2]
|
||||
. Add the Apache repository of Cassandra to the file
|
||||
`cassandra.sources.list`.
|
||||
include::partial$package_versions.adoc[]
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/get_deb_package.sh[]
|
||||
----
|
||||
|
||||
[arabic, start=3]
|
||||
. Add the Apache Cassandra repository keys to the list of trusted keys
|
||||
on the server:
|
||||
|
||||
[{tabs}]
|
||||
====
|
||||
Command::
|
||||
+
|
||||
--
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/add_repo_keys.sh[]
|
||||
include::cassandra:example$BASH/add_repo_keys.sh[]
|
||||
----
|
||||
--
|
||||
|
||||
|
|
@ -264,82 +215,68 @@ Result::
|
|||
--
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/add_repo_keys.result[]
|
||||
include::cassandra:example$RESULTS/add_repo_keys.result[]
|
||||
----
|
||||
--
|
||||
====
|
||||
|
||||
[arabic, start=4]
|
||||
. Update the package index from sources:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/apt-get_update.sh[]
|
||||
include::cassandra:example$BASH/apt-get_update.sh[]
|
||||
----
|
||||
|
||||
[arabic, start=5]
|
||||
. Install Cassandra with APT:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/apt-get_cass.sh[]
|
||||
include::cassandra:example$BASH/apt-get_cass.sh[]
|
||||
----
|
||||
+
|
||||
include::cassandra:partial$tail_syslog.adoc[]
|
||||
+
|
||||
include::cassandra:partial$nodetool_and_cqlsh_nobin.adoc[]
|
||||
|
||||
NOTE: For information on how to configure your installation, see
|
||||
{cass_url}doc/latest/getting-started/configuring.html[Configuring
|
||||
Cassandra].
|
||||
== Install as RPM package
|
||||
|
||||
include::partial$tail_syslog.adoc[]
|
||||
include::cassandra:partial$java_version.adoc[]
|
||||
|
||||
include::partial$nodetool_and_cqlsh_nobin.adoc[]
|
||||
|
||||
== Installing the RPM packages
|
||||
|
||||
include::partial$java_version.adoc[]
|
||||
|
||||
[arabic, start=2]
|
||||
. Add the Apache repository of Cassandra to the file
|
||||
`/etc/yum.repos.d/cassandra.repo` (as the `root` user).
|
||||
include::partial$package_versions.adoc[]
|
||||
|
||||
. Add the Apache repository of Cassandra to the file `/etc/yum.repos.d/cassandra.repo` (as the `root` user).
|
||||
+
|
||||
include::cassandra:partial$package_versions.adoc[]
|
||||
+
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/add_yum_repo.result[]
|
||||
include::cassandra:example$RESULTS/add_yum_repo.result[]
|
||||
----
|
||||
|
||||
[arabic, start=3]
|
||||
. Update the package index from sources:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/yum_update.sh[]
|
||||
include::cassandra:example$BASH/yum_update.sh[]
|
||||
----
|
||||
|
||||
[arabic, start=4]
|
||||
. Install Cassandra with YUM:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/yum_cass.sh[]
|
||||
include::cassandra:example$BASH/yum_cass.sh[]
|
||||
----
|
||||
|
||||
NOTE: A new Linux user `cassandra` will get created as part of the
|
||||
installation. The Cassandra service will also be run as this user.
|
||||
|
||||
[arabic, start=5]
|
||||
+
|
||||
[NOTE]
|
||||
====
|
||||
A new Linux user `cassandra` will get created as part of the installation.
|
||||
The Cassandra service will also be run as this user.
|
||||
====
|
||||
. Start the Cassandra service:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/yum_start.sh[]
|
||||
include::cassandra:example$BASH/yum_start.sh[]
|
||||
----
|
||||
|
||||
include::partial$tail_syslog.adoc[]
|
||||
|
||||
include::partial$nodetool_and_cqlsh_nobin.adoc[]
|
||||
+
|
||||
include::cassandra:partial$tail_syslog.adoc[]
|
||||
+
|
||||
include::cassandra:partial$nodetool_and_cqlsh_nobin.adoc[]
|
||||
|
||||
== Further installation info
|
||||
|
||||
For help with installation issues, see the
|
||||
{cass_url}doc/latest/troubleshooting/index.html[Troubleshooting]
|
||||
section.
|
||||
For help with installation issues, see the xref:cassandra:troubleshooting/index.html[Troubleshooting] section.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ tools.
|
|||
See each file for examples of settings.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
The `jvm-*` files replace the `cassandra-envsh` file used in Cassandra
|
||||
versions prior to Cassandra 3.0. The `cassandra-env.sh` bash script file
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ can also be set using `nodetool setlogginglevels`.
|
|||
|
||||
== Options
|
||||
|
||||
=== `appender name="<appender_choice>"...</appender>`
|
||||
=== `appender name="<appender_choice>"...</appender>`
|
||||
|
||||
Specify log type and settings. Possible appender names are: `SYSTEMLOG`,
|
||||
`DEBUGLOG`, `ASYNCDEBUGLOG`, and `STDOUT`. `SYSTEMLOG` ensures that WARN
|
||||
|
|
@ -19,7 +19,7 @@ format.
|
|||
*Example:* <appender name="SYSTEMLOG"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
|
||||
=== `<file> <filename> </file>`
|
||||
=== `<file> <filename> </file>`
|
||||
|
||||
Specify the filename for a log.
|
||||
|
||||
|
|
@ -32,9 +32,8 @@ Specify the level for a log. Part of the filter. Levels are: `ALL`,
|
|||
most verbose log, `ERROR` the least.
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
Note: Increasing logging levels can generate heavy logging output on
|
||||
Increasing logging levels can generate heavy logging output on
|
||||
a moderately trafficked cluster. You can use the
|
||||
`nodetool getlogginglevels` command to see the current logging
|
||||
configuration.
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ Datacenter and rack naming convention. Options are `legacy` or
|
|||
*Default value:* standard
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
YOU MUST USE THE `legacy` VALUE IF YOU ARE UPGRADING A PRE-4.0 CLUSTER.
|
||||
====
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
The `PropertyFileSnitch` `snitch` option uses the
|
||||
`cassandra-topologies.properties` configuration file to determine which
|
||||
`datacenters` and racks cluster nodes belong to. If other snitches are
|
||||
used, the xref:configuration/cass_rackdc_file.adoc[cassandra-rackdc.properties] must be used. The snitch determines
|
||||
used, the xref:cassandra:managing/configuration/cass_rackdc_file.adoc[cassandra-rackdc.properties] must be used. The snitch determines
|
||||
network topology (proximity by rack and datacenter) so that requests are
|
||||
routed efficiently and allows the database to distribute replicas
|
||||
evenly.
|
||||
|
|
@ -47,6 +47,6 @@ This example uses three datacenters:
|
|||
172.106.12.121=DC3:RAC1
|
||||
172.106.12.122=DC3:RAC1
|
||||
|
||||
# default for unknown nodes
|
||||
# default for unknown nodes
|
||||
default =DC3:RAC1
|
||||
----
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
This section describes how to configure Apache Cassandra.
|
||||
|
||||
* xref:configuration/cass_yaml_file.adoc[cassandra.yaml]
|
||||
* xref:configuration/cass_rackdc_file.adoc[cassandra-rackdc.properties]
|
||||
* xref:configuration/cass_env_sh_file.adoc[cassandra-env.sh]
|
||||
* xref:configuration/cass_topo_file.adoc[cassandra-topologies.properties]
|
||||
* xref:configuration/cass_cl_archive_file.adoc[commitlog-archiving.properties]
|
||||
* xref:configuration/cass_logback_xml_file.adoc[logback.xml]
|
||||
* xref:configuration/cass_jvm_options_file.adoc[jvm-* files]
|
||||
* xref:cassandra:managing/configuration/cass_yaml_file.adoc[cassandra.yaml]
|
||||
* xref:cassandra:managing/configuration/cass_rackdc_file.adoc[cassandra-rackdc.properties]
|
||||
* xref:cassandra:managing/configuration/cass_env_sh_file.adoc[cassandra-env.sh]
|
||||
* xref:cassandra:managing/configuration/cass_topo_file.adoc[cassandra-topologies.properties]
|
||||
* xref:cassandra:managing/configuration/cass_cl_archive_file.adoc[commitlog-archiving.properties]
|
||||
* xref:cassandra:managing/configuration/cass_logback_xml_file.adoc[logback.xml]
|
||||
* xref:cassandra:managing/configuration/cass_jvm_options_file.adoc[jvm-* files]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
= Managing
|
||||
|
||||
* xref:managing/configuration/index.adoc[]
|
||||
* xref:managing/operating/index.adoc[]
|
||||
* xref:managing/tools/index.adoc[]
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Audit logging in Cassandra logs every incoming CQL command request,
|
||||
as well as authentication (successful/unsuccessful login) to a Cassandra node.
|
||||
Currently, there are two implementations provided.
|
||||
Currently, there are two implementations provided.
|
||||
The custom logger can be implemented and injected with the class name as a parameter in
|
||||
the `cassandra.yaml` file.
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ successfully executed
|
|||
|
||||
Executing prepared statements will log the query as provided by the
|
||||
client in the prepare call, along with the execution timestamp and all
|
||||
other attributes (see below).
|
||||
other attributes (see below).
|
||||
Actual values bound for prepared statement execution will not show up in the audit log.
|
||||
|
||||
== What does audit logging logs
|
||||
|
|
@ -47,7 +47,7 @@ applicable
|
|||
|
||||
== How to configure
|
||||
|
||||
Auditlog can be configured using the `cassandra.yaml` file.
|
||||
Auditlog can be configured using the `cassandra.yaml` file.
|
||||
To use audit logging on one node, either edit that file or enable and configure using `nodetool`.
|
||||
|
||||
=== cassandra.yaml configurations for AuditLog
|
||||
|
|
@ -79,7 +79,7 @@ ERROR, PREPARE
|
|||
|
||||
=== NodeTool command to enable AuditLog
|
||||
|
||||
The `nodetool enableauditlog` command enables AuditLog with the `cassandra.yaml` file defaults.
|
||||
The `nodetool enableauditlog` command enables AuditLog with the `cassandra.yaml` file defaults.
|
||||
Those defaults can be overridden using options with this nodetool command.
|
||||
|
||||
[source,none]
|
||||
|
|
@ -172,7 +172,7 @@ LogMessage: user:anonymous|host:localhost/X.X.X.X|source:/X.X.X.X|port:60878|tim
|
|||
== Configuring BinAuditLogger
|
||||
|
||||
To use `BinAuditLogger` as a logger in AuditLogging, set the logger to `BinAuditLogger` in the `cassandra.yaml` file
|
||||
under the `audit_logging_options` section.
|
||||
under the `audit_logging_options` section.
|
||||
`BinAuditLogger` can be futher configued using its advanced options in `cassandra.yaml`.
|
||||
|
||||
=== Advanced Options for BinAuditLogger
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
Audit Logging is a new feature in Apache Cassandra 4.0 (https://issues.apache.org/jira/browse/CASSANDRA-12151[CASSANDRA-12151]).
|
||||
This new feature is safe for production use, with configurable limits to heap memory and disk space to prevent out-of-memory errors.
|
||||
All database activity is logged per-node as file-based records to a specified local filesystem directory.
|
||||
The audit log files are rolled periodically based on a configurable value.
|
||||
All database activity is logged per-node as file-based records to a specified local filesystem directory.
|
||||
The audit log files are rolled periodically based on a configurable value.
|
||||
|
||||
Some of the features of audit logging are:
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ Some of the features of audit logging are:
|
|||
* Can be enabled or disabled at startup time using `cassandra.yaml` or at runtime using the JMX tool, ``nodetool``.
|
||||
* Can configure the settings in either the `cassandra.yaml` file or by using ``nodetool``.
|
||||
|
||||
Audit logging includes all CQL requests, both successful and failed.
|
||||
It also captures all successful and failed authentication and authorization events, such as login attempts.
|
||||
Audit logging includes all CQL requests, both successful and failed.
|
||||
It also captures all successful and failed authentication and authorization events, such as login attempts.
|
||||
The difference between Full Query Logging (FQL) and audit logging is that FQL captures only successful CQL requests, which allow replay or comparison of logs.
|
||||
Audit logs are useful for compliance and debugging, while FQL is useful for debugging, performance benchmarking, testing and auditing CQL queries.
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ The audit log does not contain:
|
|||
** Statements that fail to parse will have everything after the appearance of the word password obfuscated as \*\*\*\*\*\*\*.
|
||||
** Statements with a mistyped word 'password' will be logged without obfuscation. Please make sure to use a different password on retries.
|
||||
|
||||
The audit log is a series of log entries.
|
||||
The audit log is a series of log entries.
|
||||
An audit log entry contains:
|
||||
|
||||
* keyspace (String) - Keyspace on which request is made
|
||||
|
|
@ -60,18 +60,18 @@ CQL audit log entry types are the following CQL commands. Each command is assign
|
|||
|===
|
||||
| Category | CQL commands
|
||||
|
||||
| DDL | ALTER_KEYSPACE, CREATE_KEYSPACE, DROP_KEYSPACE,
|
||||
ALTER_TABLE, CREATE_TABLE, DROP_TABLE,
|
||||
CREATE_FUNCTION, DROP_FUNCTION,
|
||||
CREATE_AGGREGATE, DROP_AGGREGATE,
|
||||
CREATE_INDEX, DROP_INDEX,
|
||||
| DDL | ALTER_KEYSPACE, CREATE_KEYSPACE, DROP_KEYSPACE,
|
||||
ALTER_TABLE, CREATE_TABLE, DROP_TABLE,
|
||||
CREATE_FUNCTION, DROP_FUNCTION,
|
||||
CREATE_AGGREGATE, DROP_AGGREGATE,
|
||||
CREATE_INDEX, DROP_INDEX,
|
||||
ALTER_TYPE, CREATE_TYPE, DROP_TYPE,
|
||||
CREATE_TRIGGER, DROP_TRIGGER,
|
||||
ALTER_VIEW, CREATE_VIEW, DROP_VIEW,
|
||||
TRUNCATE
|
||||
| DML | BATCH, DELETE, UPDATE
|
||||
| DCL | GRANT, REVOKE,
|
||||
ALTER_ROLE, CREATE_ROLE, DROP_ROLE,
|
||||
| DCL | GRANT, REVOKE,
|
||||
ALTER_ROLE, CREATE_ROLE, DROP_ROLE,
|
||||
LIST_ROLES, LIST_PERMISSIONS, LIST_USERS
|
||||
| OTHER | USE_KEYSPACE
|
||||
| QUERY | SELECT
|
||||
|
|
@ -148,7 +148,7 @@ TIP: You can monitor whether audit logging is enabled with ``AuditLogEnabled`` a
|
|||
|
||||
=== logger
|
||||
|
||||
The type of audit logger is set with the `logger` option.
|
||||
The type of audit logger is set with the `logger` option.
|
||||
Supported values are:
|
||||
|
||||
- `BinAuditLogger` (default)
|
||||
|
|
@ -163,7 +163,7 @@ For example:
|
|||
|
||||
[source, yaml]
|
||||
----
|
||||
logger:
|
||||
logger:
|
||||
- class_name: FileAuditLogger
|
||||
----
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ The audit log directory can also be configured using the system property `cassan
|
|||
=== included_keyspaces and excluded_keyspaces
|
||||
|
||||
Set the keyspaces to include with the `included_keyspaces` option and
|
||||
the keyspaces to exclude with the `excluded_keyspaces` option.
|
||||
the keyspaces to exclude with the `excluded_keyspaces` option.
|
||||
By default, `system`, `system_schema` and `system_virtual_schema` are excluded, and all other keyspaces are included.
|
||||
|
||||
For example:
|
||||
|
|
@ -195,8 +195,8 @@ excluded_keyspaces: system, system_schema, system_virtual_schema
|
|||
|
||||
=== included_categories and excluded_categories
|
||||
|
||||
The categories of database operations to include are specified with the `included_categories` option as a comma-separated list.
|
||||
The categories of database operations to exclude are specified with `excluded_categories` option as a comma-separated list.
|
||||
The categories of database operations to include are specified with the `included_categories` option as a comma-separated list.
|
||||
The categories of database operations to exclude are specified with `excluded_categories` option as a comma-separated list.
|
||||
The supported categories for audit log are: `AUTH`, `DCL`, `DDL`, `DML`, `ERROR`, `OTHER`, `PREPARE`, and `QUERY`.
|
||||
By default, all supported categories are included, and no category is excluded.
|
||||
|
||||
|
|
@ -208,14 +208,14 @@ excluded_categories: DDL, DML, QUERY, PREPARE
|
|||
|
||||
=== included_users and excluded_users
|
||||
|
||||
Users to audit log are set with the `included_users` and `excluded_users` options.
|
||||
Users to audit log are set with the `included_users` and `excluded_users` options.
|
||||
The `included_users` option specifies a comma-separated list of users to include explicitly.
|
||||
The `excluded_users` option specifies a comma-separated list of users to exclude explicitly.
|
||||
By default, all users are included, and no users are excluded.
|
||||
|
||||
[source, yaml]
|
||||
----
|
||||
included_users:
|
||||
included_users:
|
||||
excluded_users: john, mary
|
||||
----
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ Interval between each retry is hard coded to 5 minutes.
|
|||
|
||||
[[enabling_audit_with_nodetool]]
|
||||
== Enabling Audit Logging with ``nodetool``
|
||||
|
||||
|
||||
Audit logging is enabled on a per-node basis using the ``nodetool enableauditlog`` command. The logging directory must be defined with ``audit_logs_dir`` in the `cassandra.yaml` file or uses the default value ``cassandra.logdir.audit``.
|
||||
|
||||
The syntax of the ``nodetool enableauditlog`` command has all the same options that can be set in the ``cassandra.yaml`` file except ``audit_logs_dir``.
|
||||
|
|
@ -383,13 +383,13 @@ $ nodetool enableauditlog
|
|||
|
||||
== Disabling audit logging
|
||||
|
||||
Use the `nodetool disableauditlog` command to disable audit logging.
|
||||
Use the `nodetool disableauditlog` command to disable audit logging.
|
||||
|
||||
== Viewing audit logs
|
||||
|
||||
The `auditlogviewer` tool is used to view (dump) audit logs if the logger was ``BinAuditLogger``..
|
||||
The `auditlogviewer` tool is used to view (dump) audit logs if the logger was ``BinAuditLogger``..
|
||||
``auditlogviewer`` converts the binary log files into human-readable format; only the audit log directory must be supplied as a command-line option.
|
||||
If the logger ``FileAuditLogger`` was set, the log file are already in human-readable format and ``auditlogviewer`` is not needed to read files.
|
||||
If the logger ``FileAuditLogger`` was set, the log file are already in human-readable format and ``auditlogviewer`` is not needed to read files.
|
||||
|
||||
|
||||
The syntax of `auditlogviewer` is:
|
||||
|
|
@ -439,7 +439,7 @@ audit_logging_options:
|
|||
----
|
||||
|
||||
[arabic, start=2]
|
||||
. Create the audit log directory `/cassandra/audit/logs/hourly` and set the directory permissions to read, write, and execute for all.
|
||||
. Create the audit log directory `/cassandra/audit/logs/hourly` and set the directory permissions to read, write, and execute for all.
|
||||
|
||||
[arabic, start=3]
|
||||
. Now create a demo keyspace and table and insert some data using ``cqlsh``:
|
||||
|
|
@ -470,7 +470,7 @@ $ cd /cassandra/audit/logs/hourly
|
|||
----
|
||||
|
||||
[arabic, start=5]
|
||||
. List the audit log files and directories.
|
||||
. List the audit log files and directories.
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
|
|
@ -490,7 +490,7 @@ total 28
|
|||
The audit log files will all be listed with a `.cq4` file type. The audit directory is of `.cq4t` type.
|
||||
|
||||
[arabic, start=6]
|
||||
. Run `auditlogviewer` tool to view the audit logs.
|
||||
. Run `auditlogviewer` tool to view the audit logs.
|
||||
|
||||
[source, bash]
|
||||
----
|
||||
|
|
|
|||
|
|
@ -19,37 +19,37 @@ Apache Cassandra supports two kinds of backup strategies.
|
|||
* Incremental Backups
|
||||
|
||||
A _snapshot_ is a copy of a table’s SSTable files at a given time,
|
||||
created via hard links.
|
||||
created via hard links.
|
||||
The DDL to create the table is stored as well.
|
||||
Snapshots may be created by a user or created automatically.
|
||||
Snapshots may be created by a user or created automatically.
|
||||
The setting `snapshot_before_compaction` in the `cassandra.yaml` file determines if
|
||||
snapshots are created before each compaction.
|
||||
By default, `snapshot_before_compaction` is set to false.
|
||||
snapshots are created before each compaction.
|
||||
By default, `snapshot_before_compaction` is set to false.
|
||||
Snapshots may be created automatically before keyspace truncation or dropping of a table by
|
||||
setting `auto_snapshot` to true (default) in `cassandra.yaml`.
|
||||
setting `auto_snapshot` to true (default) in `cassandra.yaml`.
|
||||
Truncates could be delayed due to the auto snapshots and another setting in
|
||||
`cassandra.yaml` determines how long the coordinator should wait for
|
||||
truncates to complete.
|
||||
truncates to complete.
|
||||
By default Cassandra waits 60 seconds for auto snapshots to complete.
|
||||
|
||||
An _incremental backup_ is a copy of a table’s SSTable files created by
|
||||
a hard link when memtables are flushed to disk as SSTables.
|
||||
a hard link when memtables are flushed to disk as SSTables.
|
||||
Typically incremental backups are paired with snapshots to reduce the backup time
|
||||
as well as reduce disk space.
|
||||
as well as reduce disk space.
|
||||
Incremental backups are not enabled by default and must be enabled explicitly in `cassandra.yaml` (with
|
||||
`incremental_backups` setting) or with `nodetool`.
|
||||
`incremental_backups` setting) or with `nodetool`.
|
||||
Once enabled, Cassandra creates a hard link to each SSTable flushed or streamed
|
||||
locally in a `backups/` subdirectory of the keyspace data.
|
||||
locally in a `backups/` subdirectory of the keyspace data.
|
||||
Incremental backups of system tables are also created.
|
||||
|
||||
== Data Directory Structure
|
||||
|
||||
The directory structure of Cassandra data consists of different
|
||||
directories for keyspaces, and tables with the data files within the
|
||||
table directories.
|
||||
table directories.
|
||||
Directories backups and snapshots to store backups
|
||||
and snapshots respectively for a particular table are also stored within
|
||||
the table directory.
|
||||
the table directory.
|
||||
The directory structure for Cassandra is illustrated in Figure 1.
|
||||
|
||||
image::Figure_1_backups.jpg[Data directory structure for backups]
|
||||
|
|
@ -59,98 +59,98 @@ Figure 1. Directory Structure for Cassandra Data
|
|||
=== Setting Up Example Tables for Backups and Snapshots
|
||||
|
||||
In this section we shall create some example data that could be used to
|
||||
demonstrate incremental backups and snapshots.
|
||||
We have used a three node Cassandra cluster.
|
||||
First, the keyspaces are created.
|
||||
Then tables are created within a keyspace and table data is added.
|
||||
demonstrate incremental backups and snapshots.
|
||||
We have used a three node Cassandra cluster.
|
||||
First, the keyspaces are created.
|
||||
Then tables are created within a keyspace and table data is added.
|
||||
We have used two keyspaces `cqlkeyspace` and `catalogkeyspace` with two tables within
|
||||
each.
|
||||
each.
|
||||
|
||||
Create the keyspace `cqlkeyspace`:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_ks_backup.cql[]
|
||||
include::cassandra:example$CQL/create_ks_backup.cql[]
|
||||
----
|
||||
|
||||
Create two tables `t` and `t2` in the `cqlkeyspace` keyspace.
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table_backup.cql[]
|
||||
----
|
||||
|
||||
Add data to the tables:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/insert_data_backup.cql[]
|
||||
----
|
||||
|
||||
Query the table to list the data:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/select_data_backup.cql[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$RESULTS/select_data_backup.result[]
|
||||
----
|
||||
|
||||
Create a second keyspace `catalogkeyspace`:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_ks2_backup.cql[]
|
||||
----
|
||||
|
||||
Create two tables `journal` and `magazine` in `catalogkeyspace`:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/create_table2_backup.cql[]
|
||||
include::cassandra:example$CQL/create_table_backup.cql[]
|
||||
----
|
||||
|
||||
Add data to the tables:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/insert_data2_backup.cql[]
|
||||
include::cassandra:example$CQL/insert_data_backup.cql[]
|
||||
----
|
||||
|
||||
Query the table to list the data:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/select_data_backup.cql[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$RESULTS/select_data_backup.result[]
|
||||
----
|
||||
|
||||
Create a second keyspace `catalogkeyspace`:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/create_ks2_backup.cql[]
|
||||
----
|
||||
|
||||
Create two tables `journal` and `magazine` in `catalogkeyspace`:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/create_table2_backup.cql[]
|
||||
----
|
||||
|
||||
Add data to the tables:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/insert_data2_backup.cql[]
|
||||
----
|
||||
|
||||
Query the tables to list the data:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$CQL/select_data2_backup.cql[]
|
||||
include::cassandra:example$CQL/select_data2_backup.cql[]
|
||||
----
|
||||
|
||||
results in
|
||||
results in
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::example$RESULTS/select_data2_backup.result[]
|
||||
include::cassandra:example$RESULTS/select_data2_backup.result[]
|
||||
----
|
||||
|
||||
== Snapshots
|
||||
|
||||
In this section, we demonstrate creating snapshots.
|
||||
In this section, we demonstrate creating snapshots.
|
||||
The command used to create a snapshot is `nodetool snapshot` with the usage:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/nodetool_snapshot.sh[]
|
||||
include::cassandra:example$BASH/nodetool_snapshot.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/nodetool_snapshot_help.result[]
|
||||
include::cassandra:example$RESULTS/nodetool_snapshot_help.result[]
|
||||
----
|
||||
|
||||
=== Configuring for Snapshots
|
||||
|
|
@ -160,7 +160,7 @@ have set `auto_snapshots` setting to `false` in the `cassandra.yaml` file:
|
|||
|
||||
[source,yaml]
|
||||
----
|
||||
include::example$YAML/auto_snapshot.yaml[]
|
||||
include::cassandra:example$YAML/auto_snapshot.yaml[]
|
||||
----
|
||||
|
||||
Also set `snapshot_before_compaction` to `false` to disable creating
|
||||
|
|
@ -168,7 +168,7 @@ snapshots automatically before compaction:
|
|||
|
||||
[source,yaml]
|
||||
----
|
||||
include::example$YAML/snapshot_before_compaction.yaml[]
|
||||
include::cassandra:example$YAML/snapshot_before_compaction.yaml[]
|
||||
----
|
||||
|
||||
=== Creating Snapshots
|
||||
|
|
@ -177,7 +177,7 @@ Before creating any snapshots, search for snapshots and none will be listed:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/find_snapshots.sh[]
|
||||
include::cassandra:example$BASH/find_snapshots.sh[]
|
||||
----
|
||||
|
||||
We shall be using the example keyspaces and tables to create snapshots.
|
||||
|
|
@ -189,29 +189,29 @@ in the `catalogkeyspace` keyspace:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_backup2.sh[]
|
||||
include::cassandra:example$BASH/snapshot_backup2.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source,none]
|
||||
----
|
||||
include::example$RESULTS/snapshot_backup2.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_backup2.result[]
|
||||
----
|
||||
|
||||
Using the `find` command above, the snapshots and `snapshots` directories
|
||||
Using the `find` command above, the snapshots and `snapshots` directories
|
||||
are now found with listed files similar to:
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_backup2_find.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_backup2_find.result[]
|
||||
----
|
||||
|
||||
Snapshots of all tables in multiple keyspaces may be created similarly:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_both_backups.sh[]
|
||||
include::cassandra:example$BASH/snapshot_both_backups.sh[]
|
||||
----
|
||||
|
||||
==== Taking Snapshots of Single Table in a Keyspace
|
||||
|
|
@ -221,64 +221,64 @@ syntax becomes as follows:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_one_table.sh[]
|
||||
include::cassandra:example$BASH/snapshot_one_table.sh[]
|
||||
----
|
||||
|
||||
Using the syntax above, create a snapshot for table `magazine` in keyspace `catalogkeyspace`:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_one_table2.sh[]
|
||||
include::cassandra:example$BASH/snapshot_one_table2.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_one_table2.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_one_table2.result[]
|
||||
----
|
||||
|
||||
==== Taking Snapshot of Multiple Tables from same Keyspace
|
||||
|
||||
To take snapshots of multiple tables in a keyspace the list of
|
||||
_Keyspace.table_ must be specified with option `--kt-list`.
|
||||
_Keyspace.table_ must be specified with option `--kt-list`.
|
||||
For example, create snapshots for tables `t` and `t2` in the `cqlkeyspace` keyspace:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_mult_tables.sh[]
|
||||
include::cassandra:example$BASH/snapshot_mult_tables.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_mult_tables.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_mult_tables.result[]
|
||||
----
|
||||
|
||||
Multiple snapshots of the same set of tables may be created and tagged with a different name.
|
||||
As an example, create another snapshot for the same set of tables `t` and `t2` in the `cqlkeyspace`
|
||||
Multiple snapshots of the same set of tables may be created and tagged with a different name.
|
||||
As an example, create another snapshot for the same set of tables `t` and `t2` in the `cqlkeyspace`
|
||||
keyspace and tag the snapshots differently:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_mult_tables_again.sh[]
|
||||
include::cassandra:example$BASH/snapshot_mult_tables_again.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_mult_tables_again.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_mult_tables_again.result[]
|
||||
----
|
||||
|
||||
==== Taking Snapshot of Multiple Tables from Different Keyspaces
|
||||
|
||||
To take snapshots of multiple tables that are in different keyspaces the
|
||||
command syntax is the same as when multiple tables are in the same
|
||||
keyspace.
|
||||
keyspace.
|
||||
Each <keyspace>.<table> must be specified separately in the
|
||||
`--kt-list` option.
|
||||
`--kt-list` option.
|
||||
|
||||
For example, create a snapshot for table `t` in
|
||||
the `cqlkeyspace` and table `journal` in the catalogkeyspace and tag the
|
||||
|
|
@ -286,13 +286,13 @@ snapshot `multi-ks`.
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_mult_ks.sh[]
|
||||
include::cassandra:example$BASH/snapshot_mult_ks.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_mult_ks.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_mult_ks.result[]
|
||||
----
|
||||
|
||||
=== Listing Snapshots
|
||||
|
|
@ -302,14 +302,14 @@ snapshots that we created in the preceding examples get listed:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/nodetool_list_snapshots.sh[]
|
||||
include::cassandra:example$BASH/nodetool_list_snapshots.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/nodetool_list_snapshots.result[]
|
||||
include::cassandra:example$RESULTS/nodetool_list_snapshots.result[]
|
||||
----
|
||||
|
||||
=== Finding Snapshots Directories
|
||||
|
|
@ -319,29 +319,29 @@ command:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/find_snapshots.sh[]
|
||||
include::cassandra:example$BASH/find_snapshots.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_all.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_all.result[]
|
||||
----
|
||||
|
||||
To list the snapshots for a particular table first change to the snapshots directory for that table.
|
||||
To list the snapshots for a particular table first change to the snapshots directory for that table.
|
||||
For example, list the snapshots for the `catalogkeyspace/journal` table:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/find_two_snapshots.sh[]
|
||||
include::cassandra:example$BASH/find_two_snapshots.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/find_two_snapshots.result[]
|
||||
include::cassandra:example$RESULTS/find_two_snapshots.result[]
|
||||
----
|
||||
|
||||
A `snapshots` directory lists the SSTable files in the snapshot.
|
||||
|
|
@ -350,34 +350,34 @@ that can recreate the table with CQL when restoring from a snapshot:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/snapshot_files.sh[]
|
||||
include::cassandra:example$BASH/snapshot_files.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/snapshot_files.result[]
|
||||
include::cassandra:example$RESULTS/snapshot_files.result[]
|
||||
----
|
||||
|
||||
=== Clearing Snapshots
|
||||
|
||||
Snapshots may be cleared or deleted with the `nodetool clearsnapshot`
|
||||
command. Either a specific snapshot name must be specified or the `–all`
|
||||
option must be specified.
|
||||
option must be specified.
|
||||
|
||||
For example, delete a snapshot called `magazine` from keyspace `cqlkeyspace`:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/nodetool_clearsnapshot.sh[]
|
||||
include::cassandra:example$BASH/nodetool_clearsnapshot.sh[]
|
||||
----
|
||||
|
||||
or delete all snapshots from `cqlkeyspace` with the –all option:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/nodetool_clearsnapshot_all.sh[]
|
||||
include::cassandra:example$BASH/nodetool_clearsnapshot_all.sh[]
|
||||
----
|
||||
|
||||
== Incremental Backups
|
||||
|
|
@ -392,17 +392,17 @@ To create incremental backups set `incremental_backups` to `true` in
|
|||
|
||||
[source,yaml]
|
||||
----
|
||||
include::example$YAML/incremental_bups.yaml[]
|
||||
include::cassandra:example$YAML/incremental_bups.yaml[]
|
||||
----
|
||||
|
||||
This is the only setting needed to create incremental backups.
|
||||
This is the only setting needed to create incremental backups.
|
||||
By default `incremental_backups` setting is set to `false` because a new
|
||||
set of SSTable files is created for each data flush and if several CQL
|
||||
statements are to be run the `backups` directory could fill up quickly
|
||||
and use up storage that is needed to store table data.
|
||||
and use up storage that is needed to store table data.
|
||||
Incremental backups may also be enabled on the command line with the nodetool
|
||||
command `nodetool enablebackup`.
|
||||
Incremental backups may be disabled with `nodetool disablebackup` command.
|
||||
command `nodetool enablebackup`.
|
||||
Incremental backups may be disabled with `nodetool disablebackup` command.
|
||||
Status of incremental backups, whether they are enabled may be checked with `nodetool statusbackup`.
|
||||
|
||||
=== Creating Incremental Backups
|
||||
|
|
@ -412,7 +412,7 @@ command. Incremental backups get created.
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/nodetool_flush.sh[]
|
||||
include::cassandra:example$BASH/nodetool_flush.sh[]
|
||||
----
|
||||
|
||||
=== Finding Incremental Backups
|
||||
|
|
@ -422,12 +422,12 @@ within a table directory. Backups may be found with following command.
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/find_backups.sh[]
|
||||
include::cassandra:example$BASH/find_backups.sh[]
|
||||
----
|
||||
results in
|
||||
[source,none]
|
||||
----
|
||||
include::example$RESULTS/find_backups.result[]
|
||||
include::cassandra:example$RESULTS/find_backups.result[]
|
||||
----
|
||||
|
||||
=== Creating an Incremental Backup
|
||||
|
|
@ -439,7 +439,7 @@ Flush the keyspace and table:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/nodetool_flush_table.sh[]
|
||||
include::cassandra:example$BASH/nodetool_flush_table.sh[]
|
||||
----
|
||||
|
||||
A search for backups and a `backups` directory will list a backup directory,
|
||||
|
|
@ -447,28 +447,28 @@ even if we have added no table data yet.
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/find_backups.sh[]
|
||||
include::cassandra:example$BASH/find_backups.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/find_backups_table.result[]
|
||||
include::cassandra:example$RESULTS/find_backups_table.result[]
|
||||
----
|
||||
|
||||
Checking the `backups` directory will show that there are also no backup files:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/check_backups.sh[]
|
||||
include::cassandra:example$BASH/check_backups.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/no_bups.result[]
|
||||
include::cassandra:example$RESULTS/no_bups.result[]
|
||||
----
|
||||
|
||||
If a row of data is added to the data, running the `nodetool flush` command will
|
||||
|
|
@ -476,18 +476,17 @@ flush the table data and an incremental backup will be created:
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::example$BASH/flush_and_check.sh[]
|
||||
include::cassandra:example$BASH/flush_and_check.sh[]
|
||||
----
|
||||
|
||||
results in
|
||||
results in
|
||||
|
||||
[source, plaintext]
|
||||
----
|
||||
include::example$RESULTS/flush_and_check.result[]
|
||||
include::cassandra:example$RESULTS/flush_and_check.result[]
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
.note
|
||||
====
|
||||
The `backups` directory for any table, such as `cqlkeyspace/t` is created in the
|
||||
`data` directory for that table.
|
||||
|
|
@ -499,7 +498,7 @@ second:
|
|||
|
||||
[source,none]
|
||||
----
|
||||
include::example$RESULTS/flush_and_check2.result[]
|
||||
include::cassandra:example$RESULTS/flush_and_check2.result[]
|
||||
----
|
||||
|
||||
== Restoring from Incremental Backups and Snapshots
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
= Bulk Loading
|
||||
|
||||
Bulk loading Apache Cassandra data is supported by different tools.
|
||||
Bulk loading Apache Cassandra data is supported by different tools.
|
||||
The data to bulk load must be in the form of SSTables.
|
||||
Cassandra does not support loading data in any other format such as CSV,
|
||||
JSON, and XML directly.
|
||||
JSON, and XML directly.
|
||||
Although the cqlsh `COPY` command can load CSV data, it is not a good option
|
||||
for amounts of data.
|
||||
for amounts of data.
|
||||
Bulk loading is used to:
|
||||
|
||||
* Restore incremental backups and snapshots. Backups and snapshots are
|
||||
|
|
@ -23,15 +23,15 @@ Cassandra provides two commands or tools for bulk loading data:
|
|||
|
||||
The `sstableloader` and `nodetool import` are accessible if the
|
||||
Cassandra installation `bin` directory is in the `PATH` environment
|
||||
variable.
|
||||
Or these may be accessed directly from the `bin` directory.
|
||||
The examples use the keyspaces and tables created in xref:cql/operating/backups.adoc[Backups].
|
||||
variable.
|
||||
Or these may be accessed directly from the `bin` directory.
|
||||
The examples use the keyspaces and tables created in xref:cassandra:developing/cql/operating/backups.adoc[Backups].
|
||||
|
||||
== Using sstableloader
|
||||
|
||||
The `sstableloader` is the main tool for bulk uploading data.
|
||||
`sstableloader` streams SSTable data files to a running cluster,
|
||||
conforming to the replication strategy and replication factor.
|
||||
The `sstableloader` is the main tool for bulk uploading data.
|
||||
`sstableloader` streams SSTable data files to a running cluster,
|
||||
conforming to the replication strategy and replication factor.
|
||||
The table to upload data to does need not to be empty.
|
||||
|
||||
The only requirements to run `sstableloader` are:
|
||||
|
|
@ -46,20 +46,20 @@ sstableloader [options] <dir_path>
|
|||
----
|
||||
|
||||
Sstableloader bulk loads the SSTables found in the directory
|
||||
`<dir_path>` to the configured cluster.
|
||||
The `<dir_path>` is used as the target _keyspace/table_ name.
|
||||
For example, to load an SSTable named `Standard1-g-1-Data.db` into `Keyspace1/Standard1`,
|
||||
`<dir_path>` to the configured cluster.
|
||||
The `<dir_path>` is used as the target _keyspace/table_ name.
|
||||
For example, to load an SSTable named `Standard1-g-1-Data.db` into `Keyspace1/Standard1`,
|
||||
you will need to have the files `Standard1-g-1-Data.db` and `Standard1-g-1-Index.db` in a
|
||||
directory `/path/to/Keyspace1/Standard1/`.
|
||||
|
||||
=== Sstableloader Option to accept Target keyspace name
|
||||
|
||||
Often as part of a backup strategy, some Cassandra DBAs store an entire data directory.
|
||||
When corruption in the data is found, restoring data in the same cluster (for large clusters 200 nodes)
|
||||
Often as part of a backup strategy, some Cassandra DBAs store an entire data directory.
|
||||
When corruption in the data is found, restoring data in the same cluster (for large clusters 200 nodes)
|
||||
is common, but with a different keyspace name.
|
||||
|
||||
Currently `sstableloader` derives keyspace name from the folder structure.
|
||||
As an option, to specify target keyspace name as part of `sstableloader`,
|
||||
Currently `sstableloader` derives keyspace name from the folder structure.
|
||||
As an option, to specify target keyspace name as part of `sstableloader`,
|
||||
version 4.0 adds support for the `--target-keyspace` option
|
||||
(https://issues.apache.org/jira/browse/CASSANDRA-13884[CASSANDRA-13884]).
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ The following options are supported, with `-d,--nodes <initial hosts>` required:
|
|||
----
|
||||
|
||||
The `cassandra.yaml` file can be provided on the command-line with `-f` option to set up streaming throughput, client and server encryption
|
||||
options.
|
||||
options.
|
||||
Only `stream_throughput_outbound_megabits_per_sec`, `server_encryption_options` and `client_encryption_options` are read
|
||||
from the `cassandra.yaml` file.
|
||||
You can override options read from `cassandra.yaml` with corresponding command line options.
|
||||
|
|
@ -144,7 +144,7 @@ You can override options read from `cassandra.yaml` with corresponding command l
|
|||
=== A sstableloader Demo
|
||||
|
||||
An example shows how to use `sstableloader` to upload incremental backup data for the table `catalogkeyspace.magazine`.
|
||||
In addition, a snapshot of the same table is created to bulk upload, also with `sstableloader`.
|
||||
In addition, a snapshot of the same table is created to bulk upload, also with `sstableloader`.
|
||||
|
||||
The backups and snapshots for the `catalogkeyspace.magazine` table are listed as follows:
|
||||
|
||||
|
|
@ -166,14 +166,14 @@ The directory path structure of SSTables to be uploaded using
|
|||
`sstableloader` is used as the target keyspace/table.
|
||||
You can directly upload from the `backups` and `snapshots`
|
||||
directories respectively, if the directory structure is in the format
|
||||
used by `sstableloader`.
|
||||
used by `sstableloader`.
|
||||
But the directory path of backups and snapshots for SSTables is
|
||||
`/catalogkeyspace/magazine-446eae30c22a11e9b1350d927649052c/backups` and
|
||||
`/catalogkeyspace/magazine-446eae30c22a11e9b1350d927649052c/snapshots`
|
||||
respectively, and cannot be used to upload SSTables to
|
||||
`catalogkeyspace.magazine` table.
|
||||
The directory path structure must be `/catalogkeyspace/magazine/` to use `sstableloader`.
|
||||
Create a new directory structure to upload SSTables with `sstableloader`
|
||||
`catalogkeyspace.magazine` table.
|
||||
The directory path structure must be `/catalogkeyspace/magazine/` to use `sstableloader`.
|
||||
Create a new directory structure to upload SSTables with `sstableloader`
|
||||
located at `/catalogkeyspace/magazine` and set appropriate permissions.
|
||||
|
||||
[source,bash]
|
||||
|
|
@ -184,9 +184,9 @@ $ sudo chmod -R 777 /catalogkeyspace/magazine
|
|||
|
||||
==== Bulk Loading from an Incremental Backup
|
||||
|
||||
An incremental backup does not include the DDL for a table; the table must already exist.
|
||||
If the table was dropped, it can be created using the `schema.cql` file generated with every snapshot of a table.
|
||||
Prior to using `sstableloader` to load SSTables to the `magazine` table, the table must exist.
|
||||
An incremental backup does not include the DDL for a table; the table must already exist.
|
||||
If the table was dropped, it can be created using the `schema.cql` file generated with every snapshot of a table.
|
||||
Prior to using `sstableloader` to load SSTables to the `magazine` table, the table must exist.
|
||||
The table does not need to be empty but we have used an empty table as indicated by a CQL query:
|
||||
|
||||
[source,cql]
|
||||
|
|
@ -226,7 +226,7 @@ $ sstableloader --nodes 10.0.2.238 /catalogkeyspace/magazine/
|
|||
----
|
||||
|
||||
results in
|
||||
|
||||
|
||||
[source,none]
|
||||
----
|
||||
Opening SSTables and calculating sections to stream
|
||||
|
|
@ -304,7 +304,7 @@ $ sudo cp ./cassandra/data/data/catalogkeyspace/magazine-446eae30c22a11e9b1350d9
|
|||
/catalogkeyspace/magazine
|
||||
----
|
||||
|
||||
List the files in the `/catalogkeyspace/magazine` directory.
|
||||
List the files in the `/catalogkeyspace/magazine` directory.
|
||||
The `schema.cql` will also be listed.
|
||||
|
||||
[source,bash]
|
||||
|
|
@ -339,7 +339,7 @@ $ ln -s <path_to_snapshot_folder> <keyspace_name>/<table_name>
|
|||
----
|
||||
|
||||
If the `magazine` table was dropped, run the DDL in the `schema.cql` to
|
||||
create the table.
|
||||
create the table.
|
||||
Run the `sstableloader` with the following command:
|
||||
|
||||
[source,bash]
|
||||
|
|
@ -382,7 +382,7 @@ any data in memtables.
|
|||
== Using nodetool import
|
||||
|
||||
Importing SSTables into a table using the `nodetool import` command is recommended instead of the deprecated
|
||||
`nodetool refresh` command.
|
||||
`nodetool refresh` command.
|
||||
The `nodetool import` command has an option to load new SSTables from a separate directory.
|
||||
|
||||
The command usage is as follows:
|
||||
|
|
@ -454,7 +454,7 @@ The following options are supported:
|
|||
|
||||
Because the keyspace and table are specified on the command line for
|
||||
`nodetool import`, there is not the same requirement as with
|
||||
`sstableloader`, to have the SSTables in a specific directory path.
|
||||
`sstableloader`, to have the SSTables in a specific directory path.
|
||||
When importing snapshots or incremental backups with
|
||||
`nodetool import`, the SSTables don’t need to be copied to another
|
||||
directory.
|
||||
|
|
@ -462,14 +462,14 @@ directory.
|
|||
=== Importing Data from an Incremental Backup
|
||||
|
||||
Using `nodetool import` to import SSTables from an incremental backup, and restoring
|
||||
the table is shown below.
|
||||
the table is shown below.
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
DROP table t;
|
||||
----
|
||||
|
||||
An incremental backup for a table does not include the schema definition for the table.
|
||||
An incremental backup for a table does not include the schema definition for the table.
|
||||
If the schema definition is not kept as a separate
|
||||
backup, the `schema.cql` from a backup of the table may be used to
|
||||
create the table as follows:
|
||||
|
|
@ -516,7 +516,7 @@ id | k | v
|
|||
----
|
||||
|
||||
Run the `nodetool import` command, providing the keyspace, table and
|
||||
the backups directory.
|
||||
the backups directory.
|
||||
Don’t copy the table backups to another directory, as with `sstableloader`.
|
||||
|
||||
[source,bash]
|
||||
|
|
@ -544,7 +544,7 @@ id | k | v
|
|||
=== Importing Data from a Snapshot
|
||||
|
||||
Importing SSTables from a snapshot with the `nodetool import` command is
|
||||
similar to importing SSTables from an incremental backup.
|
||||
similar to importing SSTables from an incremental backup.
|
||||
Shown here is an import of a snapshot for table `catalogkeyspace.journal`, after
|
||||
dropping the table to demonstrate the restore.
|
||||
|
||||
|
|
@ -554,7 +554,7 @@ USE CATALOGKEYSPACE;
|
|||
DROP TABLE journal;
|
||||
----
|
||||
|
||||
Use the `catalog-ks` snapshot for the `journal` table.
|
||||
Use the `catalog-ks` snapshot for the `journal` table.
|
||||
Check the files in the snapshot, and note the existence of the `schema.cql` file.
|
||||
|
||||
[source,bash]
|
||||
|
|
@ -637,10 +637,10 @@ id | name | publisher
|
|||
Bulk loading external data directly is not supported by any of the tools
|
||||
we have discussed which include `sstableloader` and `nodetool import`.
|
||||
The `sstableloader` and `nodetool import` require data to be in the form
|
||||
of SSTables.
|
||||
of SSTables.
|
||||
Apache Cassandra supports a Java API for generating SSTables from input data, using the
|
||||
`org.apache.cassandra.io.sstable.CQLSSTableWriter` Java class.
|
||||
Subsequently, either `sstableloader` or `nodetool import` is used to bulk load the SSTables.
|
||||
Subsequently, either `sstableloader` or `nodetool import` is used to bulk load the SSTables.
|
||||
|
||||
=== Generating SSTables with CQLSSTableWriter Java API
|
||||
|
||||
|
|
@ -700,15 +700,15 @@ Create a File object for the output directory.
|
|||
File outputDir = new File(OUTPUT_DIR + File.separator + "CQLKeyspace" + File.separator + "t");
|
||||
----
|
||||
|
||||
Obtain a `CQLSSTableWriter.Builder` object using `static` method `CQLSSTableWriter.builder()`.
|
||||
Obtain a `CQLSSTableWriter.Builder` object using `static` method `CQLSSTableWriter.builder()`.
|
||||
Set the following items:
|
||||
|
||||
* output directory `File` object
|
||||
* user-defined type
|
||||
* SSTable schema
|
||||
* buffer size
|
||||
* prepared statement
|
||||
* optionally any of the other builder options
|
||||
* output directory `File` object
|
||||
* user-defined type
|
||||
* SSTable schema
|
||||
* buffer size
|
||||
* prepared statement
|
||||
* optionally any of the other builder options
|
||||
|
||||
and invoke the `build()` method to create a `CQLSSTableWriter` object:
|
||||
|
||||
|
|
@ -791,7 +791,7 @@ insertion statement used when creating by this SSTable writer.
|
|||
to the writer given already serialized binary values. Returns a
|
||||
CQLSSTableWriter object. The row values must correspond to the bind
|
||||
variables of the insertion statement used when creating by this SSTable
|
||||
writer.
|
||||
writer.
|
||||
|
||||
|rawAddRow(java.util.Map<java.lang.String, java.nio.ByteBuffer> values)
|
||||
|Adds a new row to the writer given already serialized binary values.
|
||||
|
|
@ -803,7 +803,7 @@ SSTable writer.
|
|||
SSTable Writer that can be used to create UDTValue instances.
|
||||
|===
|
||||
|
||||
Other public methods the `CQLSSTableWriter.Builder` class provides are:
|
||||
Other public methods the `CQLSSTableWriter.Builder` class provides are:
|
||||
|
||||
[cols=",",options="header",]
|
||||
|===
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Change data capture (CDC) provides a mechanism to flag specific tables
|
|||
for archival as well as rejecting writes to those tables once a
|
||||
configurable size-on-disk for the CDC log is reached. An operator can
|
||||
enable CDC on a table by setting the table property `cdc=true` (either
|
||||
when xref:cql/ddl.adoc#create-table[`creating the table`] or
|
||||
xref:cql/ddl.adoc#alter-table[`altering it`]). Upon CommitLogSegment creation,
|
||||
when xref:cassandra:developing/cql/ddl.adoc#create-table[`creating the table`] or
|
||||
xref:cassandra:developing/cql/ddl.adoc#alter-table[`altering it`]). Upon CommitLogSegment creation,
|
||||
a hard-link to the segment is created in the directory specified in
|
||||
`cassandra.yaml`. On segment fsync to disk, if CDC data is present
|
||||
anywhere in the segment a <segment_name>_cdc.idx file is also created
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@
|
|||
Picking the right compaction strategy for your workload will ensure the
|
||||
best performance for both querying and for compaction itself.
|
||||
|
||||
xref:operating/compaction/stcs.adoc[`Size Tiered Compaction Strategy (STCS)`]::
|
||||
xref:cassandra:managing/operating/compaction/stcs.adoc[`Size Tiered Compaction Strategy (STCS)`]::
|
||||
The default compaction strategy. Useful as a fallback when other
|
||||
strategies don't fit the workload. Most useful for non pure time
|
||||
series workloads with spinning disks, or when the I/O from `LCS`
|
||||
is too high.
|
||||
xref:operating/compaction/lcs.adoc[`Leveled Compaction Strategy (LCS)`]::
|
||||
xref:cassandra:managing/operating/compaction/lcs.adoc[`Leveled Compaction Strategy (LCS)`]::
|
||||
Leveled Compaction Strategy (LCS) is optimized for read heavy
|
||||
workloads, or workloads with lots of updates and deletes. It is not a
|
||||
good choice for immutable time series data.
|
||||
xref:operating/compaction/twcs.adoc[`Time Window Compaction Strategy (TWCS)`]::
|
||||
xref:cassandra:managing/operating/compaction/twcs.adoc[`Time Window Compaction Strategy (TWCS)`]::
|
||||
Time Window Compaction Strategy is designed for TTL'ed, mostly
|
||||
immutable time series data.
|
||||
|
||||
|
|
@ -59,8 +59,8 @@ Sub range compaction::
|
|||
== When is a minor compaction triggered?
|
||||
|
||||
* When an sstable is added to the node through flushing/streaming
|
||||
* When autocompaction is enabled after being disabled (`nodetool enableautocompaction`)
|
||||
* When compaction adds new SSTables
|
||||
* When autocompaction is enabled after being disabled (`nodetool enableautocompaction`)
|
||||
* When compaction adds new SSTables
|
||||
* A check for new minor compactions every 5 minutes
|
||||
|
||||
== Merging SSTables
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ Users can set compression using the following syntax:
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
CREATE TABLE keyspace.table (id int PRIMARY KEY)
|
||||
CREATE TABLE keyspace.table (id int PRIMARY KEY)
|
||||
WITH compression = {'class': 'LZ4Compressor'};
|
||||
----
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ Or
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
ALTER TABLE keyspace.table
|
||||
ALTER TABLE keyspace.table
|
||||
WITH compression = {'class': 'LZ4Compressor', 'chunk_length_in_kb': 64, 'crc_check_chance': 0.5};
|
||||
----
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ Once enabled, compression can be disabled with `ALTER TABLE` setting
|
|||
|
||||
[source,cql]
|
||||
----
|
||||
ALTER TABLE keyspace.table
|
||||
ALTER TABLE keyspace.table
|
||||
WITH compression = {'enabled':'false'};
|
||||
----
|
||||
|
||||
|
|
@ -171,8 +171,8 @@ the CPU overhead of compression can be a limiting factor.
|
|||
* To prevent slow compressors (`Zstd`, `Deflate`, `LZ4HC`) from blocking
|
||||
flushes for too long, all three flush with the default fast `LZ4`
|
||||
compressor and then rely on normal compaction to re-compress the data
|
||||
into the desired compression strategy. See [.title-ref]#CASSANDRA-15379
|
||||
<https://issues.apache.org/jira/browse/CASSANDRA-15379># for more
|
||||
into the desired compression strategy.
|
||||
See https://issues.apache.org/jira/browse/CASSANDRA-15379[CASSANDRA-15379] for more
|
||||
details.
|
||||
* The compression path checksums data to ensure correctness - while the
|
||||
traditional Cassandra read path does not have a way to ensure
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Apache Cassandra 4.0 adds a new highly performant feature that supports live query logging (https://issues.apache.org/jira/browse/CASSANDRA-13983[CASSANDRA-13983]).
|
||||
FQL is safe for production use, with configurable limits to heap memory and disk space to prevent out-of-memory errors.
|
||||
This feature is useful for live traffic capture, as well as traffic replay.
|
||||
This feature is useful for live traffic capture, as well as traffic replay.
|
||||
The tool provided can be used for both debugging query traffic and migration.
|
||||
New ``nodetool`` options are also added to enable, disable or reset FQL, as well as a new tool to read and replay the binary logs.
|
||||
The full query logging (FQL) capability uses http://github.com/OpenHFT/Chronicle-Queue[Chronicle-Queue] to rotate a log of queries.
|
||||
|
|
@ -33,7 +33,7 @@ The query log contains:
|
|||
* any parameters necessary to bind wildcard values
|
||||
* all query options
|
||||
|
||||
The logger writes single or batched CQL queries after they finish, so only successfully completed queries are logged.
|
||||
The logger writes single or batched CQL queries after they finish, so only successfully completed queries are logged.
|
||||
Failed or timed-out queries are not logged. Different data is logged, depending on the type of query.
|
||||
|
||||
A single CQL query log entry contains:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ for later application to the unavailable replica. Hints are an important
|
|||
way to help reduce the duration of data inconsistency. Coordinators
|
||||
replay hints quickly after unavailable replica nodes return to the ring.
|
||||
Hints are best effort, however, and do not guarantee eventual
|
||||
consistency like xref:operating/repair.adoc[`anti-entropy repair`] does.
|
||||
consistency like xref:cassandra:managing/operating/repair.adoc[`anti-entropy repair`] does.
|
||||
|
||||
Hints are useful because of how Apache Cassandra replicates data to
|
||||
provide fault tolerance, high availability and durability. Cassandra
|
||||
|
|
@ -128,7 +128,7 @@ hinted_handoff_disabled_datacenters:
|
|||
|`unset`
|
||||
|
||||
|`max_hint_window` |Defines the maximum amount of time a node
|
||||
shall have hints generated after it has failed. |`3h`
|
||||
shall have hints generated after it has failed. |`3h`
|
||||
|
||||
|`hinted_handoff_throttle` |Maximum throttle in KiBs per second,
|
||||
per delivery thread. This will be reduced proportionally to the number
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
== Operating Cassandra
|
||||
= Operating Cassandra
|
||||
|
||||
* xref:operating/hardware.adoc[Hardware]
|
||||
* xref:operating/security.adoc[Security]
|
||||
* xref:operating/topo_changes.adoc[Topology changes]
|
||||
* xref:operating/hints.adoc[Hints]
|
||||
* xref:operating/repair.adoc[Repair]
|
||||
* xref:operating/read_repair.adoc[Read repair]
|
||||
* xref:operating/backups.adoc[Backups]
|
||||
* xref:operating/compression.adoc[Compression]
|
||||
* xref:operating/compaction/index.adoc[Compaction]
|
||||
* xref:operating/metrics.adoc[Monitoring]
|
||||
* xref:operating/bulk_loading.adoc[Bulk loading]
|
||||
* xref:operating/cdc.adoc[CDC]
|
||||
* xref:operating/bloom_filters.adoc[Bloom filters]
|
||||
* xref:operating/denylisting_partitions.adoc[Denylisting partitions]
|
||||
* xref:cassandra:managing/operating/hardware.adoc[Hardware]
|
||||
* xref:cassandra:managing/operating/security.adoc[Security]
|
||||
* xref:cassandra:managing/operating/topo_changes.adoc[Topology changes]
|
||||
* xref:cassandra:managing/operating/hints.adoc[Hints]
|
||||
* xref:cassandra:managing/operating/repair.adoc[Repair]
|
||||
* xref:cassandra:managing/operating/read_repair.adoc[Read repair]
|
||||
* xref:cassandra:managing/operating/backups.adoc[Backups]
|
||||
* xref:cassandra:managing/operating/compression.adoc[Compression]
|
||||
* xref:cassandra:managing/operating/compaction/index.adoc[Compaction]
|
||||
* xref:cassandra:managing/operating/metrics.adoc[Monitoring]
|
||||
* xref:cassandra:managing/operating/bulk_loading.adoc[Bulk loading]
|
||||
* xref:cassandra:managing/operating/cdc.adoc[CDC]
|
||||
* xref:cassandra:managing/operating/bloom_filters.adoc[Bloom filters]
|
||||
* xref:cassandra:managing/operating/denylisting_partitions.adoc[Denylisting partitions]
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ using the `role_manager` setting in `cassandra.yaml`. The default
|
|||
setting uses `CassandraRoleManager`, an implementation which stores role
|
||||
information in the tables of the `system_auth` keyspace.
|
||||
|
||||
See also the xref:cql/security.adoc#database-roles[`CQL documentation on roles`].
|
||||
See also the xref:cassandra:developing/cql/security.adoc#database-roles[`CQL documentation on roles`].
|
||||
|
||||
== Authentication
|
||||
|
||||
|
|
@ -268,7 +268,7 @@ ALTER ROLE cassandra WITH SUPERUSER = false AND LOGIN = false;
|
|||
|
||||
[arabic, start=7]
|
||||
. Finally, set up the roles and credentials for your application users
|
||||
with xref:cql/security.adoc#create-role[`CREATE ROLE`] statements.
|
||||
with xref:cassandra:developing/cql/security.adoc#create-role[`CREATE ROLE`] statements.
|
||||
|
||||
At the end of these steps, the one node is configured to use password
|
||||
authentication. To roll that out across the cluster, repeat steps 2 and
|
||||
|
|
@ -276,13 +276,13 @@ authentication. To roll that out across the cluster, repeat steps 2 and
|
|||
authentication will be fully enabled throughout the cluster.
|
||||
|
||||
Note that using `PasswordAuthenticator` also requires the use of
|
||||
xref:cql/security.adoc#operation-roles[`CassandraRoleManager`].
|
||||
xref:cassandra:developing/cql/security.adoc#operation-roles[`CassandraRoleManager`].
|
||||
|
||||
See also: `setting-credentials-for-internal-authentication`,
|
||||
xref:cql/security.adoc#create-role[`CREATE ROLE`],
|
||||
xref:cql/security.adoc#alter-role[`ALTER ROLE`],
|
||||
xref:xref:cql/security.adoc#alter-keyspace[`ALTER KEYSPACE`] and
|
||||
xref:cql/security.adoc#grant-permission[`GRANT PERMISSION`].
|
||||
xref:cassandra:developing/cql/security.adoc#create-role[`CREATE ROLE`],
|
||||
xref:cassandra:developing/cql/security.adoc#alter-role[`ALTER ROLE`],
|
||||
xref:xref:cassandra:developing/cql/security.adoc#alter-keyspace[`ALTER KEYSPACE`] and
|
||||
xref:cassandra:developing/cql/security.adoc#grant-permission[`GRANT PERMISSION`].
|
||||
|
||||
== Authorization
|
||||
|
||||
|
|
@ -347,9 +347,9 @@ GRANT SELECT ON ks.t1 TO db_user;
|
|||
and 2 for each node in turn. As each node restarts and clients
|
||||
reconnect, the enforcement of the granted permissions will begin.
|
||||
|
||||
See also: xref:cql/security.adoc#grant-permission[`GRANT PERMISSION`],
|
||||
xref:cql/security.adoc#grant-all[`GRANT ALL`] and
|
||||
xref:cql/security.adoc#revoke-permission[`REVOKE PERMISSION`].
|
||||
See also: xref:cassandra:developing/cql/security.adoc#grant-permission[`GRANT PERMISSION`],
|
||||
xref:cassandra:developing/cql/security.adoc#grant-all[`GRANT ALL`] and
|
||||
xref:cassandra:developing/cql/security.adoc#revoke-permission[`REVOKE PERMISSION`].
|
||||
|
||||
[[auth-caching]]
|
||||
== Caching
|
||||
|
|
@ -408,7 +408,7 @@ Note that by default, local-only connections are not subject to
|
|||
authentication, but this can be enabled.
|
||||
|
||||
If enabling remote connections, it is recommended to also use
|
||||
xref:operating/security.adoc#jmx-with-ssl[`SSL`] connections.
|
||||
xref:cassandra:managing/operating/security.adoc#jmx-with-ssl[`SSL`] connections.
|
||||
|
||||
Finally, after enabling auth and/or SSL, ensure that tools which use
|
||||
JMX, such as xref:tools/nodetool/nodetools.adoc[`nodetool`] are correctly configured and working
|
||||
|
|
@ -482,7 +482,7 @@ With this option, the same database roles used for CQL authentication
|
|||
can be used to control access to JMX, so updates can be managed
|
||||
centrally using just `cqlsh`. Furthermore, fine grained control over
|
||||
exactly which operations are permitted on particular MBeans can be
|
||||
acheived via xref:cql/security.adoc#grant-permission[`GRANT PERMISSION`].
|
||||
acheived via xref:cassandra:developing/cql/security.adoc#grant-permission[`GRANT PERMISSION`].
|
||||
|
||||
To enable integrated authentication, edit `cassandra-env.sh` to
|
||||
uncomment these lines:
|
||||
|
|
@ -555,7 +555,7 @@ Adding/removing roles and granting/revoking of permissions is handled
|
|||
dynamically once the initial setup is complete, so no further restarts
|
||||
are required if permissions are altered.
|
||||
|
||||
See also: xref:cql/security.adoc#permissions[`Permissions`].
|
||||
See also: xref:cassandra:developing/cql/security.adoc#permissions[`Permissions`].
|
||||
|
||||
=== JMX With SSL
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ node that is being replaced. (See CASSANDRA-8523 and CASSANDRA-12344)
|
|||
Once the bootstrapping is complete the node will be marked "UP".
|
||||
|
||||
[NOTE]
|
||||
.Note
|
||||
====
|
||||
If any of the following cases apply, you *MUST* run repair to make the
|
||||
replaced node consistent again, since it missed ongoing writes
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
= Transient Replication
|
||||
|
||||
*Note*:
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
Transient Replication
|
||||
(https://issues.apache.org/jira/browse/CASSANDRA-14404[CASSANDRA-14404])
|
||||
is an experimental feature designed for expert Apache Cassandra users
|
||||
|
|
@ -16,6 +16,7 @@ anticipated that a future version will support monotonic reads with
|
|||
transient replication as well as LWT, logged batches, and counters.
|
||||
Being experimental, Transient replication is *not* recommended for
|
||||
production use.
|
||||
====
|
||||
|
||||
== Objective
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
= Virtual Tables
|
||||
|
||||
Apache Cassandra 4.0 implements virtual tables (https://issues.apache.org/jira/browse/CASSANDRA-7622[CASSANDRA-7622]).
|
||||
Virtual tables are tables backed by an API instead of data explicitly managed and stored as SSTables.
|
||||
Apache Cassandra 4.0 implements a virtual keyspace interface for virtual tables.
|
||||
Virtual tables are tables backed by an API instead of data explicitly managed and stored as SSTables.
|
||||
Apache Cassandra 4.0 implements a virtual keyspace interface for virtual tables.
|
||||
Virtual tables are specific to each node.
|
||||
|
||||
Some of the features of virtual tables are the ability to:
|
||||
|
|
@ -18,17 +18,16 @@ Virtual keyspaces and tables are quite different from regular tables and keyspac
|
|||
* Virtual tables are local only, non-distributed, and thus not replicated.
|
||||
* Virtual tables have no associated SSTables.
|
||||
* Consistency level of the queries sent to virtual tables are ignored.
|
||||
* All existing virtual tables use `LocalPartitioner`.
|
||||
* All existing virtual tables use `LocalPartitioner`.
|
||||
Since a virtual table is not replicated the partitioner sorts in order of partition keys instead of by their hash.
|
||||
* Making advanced queries using `ALLOW FILTERING` and aggregation functions can be executed in virtual tables, even though in normal tables we do not recommend it.
|
||||
From https://issues.apache.org/jira/browse/CASSANDRA-18238[CASSANDRA-18238], it is not necessary to specify `ALLOW FILTERING` when a query would normally require that, except when querying the table `system_views.system_logs`.
|
||||
* Making advanced queries using `ALLOW FILTERING` and aggregation functions can be executed in virtual tables, even though it is not recommended in normal tables.
|
||||
|
||||
== Virtual Keyspaces
|
||||
|
||||
Apache Cassandra 4.0 has added two new keyspaces for virtual tables:
|
||||
|
||||
* `system_virtual_schema`
|
||||
* `system_views`.
|
||||
* `system_virtual_schema`
|
||||
* `system_views`.
|
||||
|
||||
The `system_virtual_schema` keyspace has three tables: `keyspaces`,
|
||||
`columns` and `tables` for the virtual keyspace, table, and column definitions, respectively.
|
||||
|
|
@ -39,9 +38,9 @@ The `system_views` keyspace contains the actual virtual tables.
|
|||
|
||||
== Virtual Table Limitations
|
||||
|
||||
Before disccusing virtual keyspaces and tables, note that virtual keyspaces and tables have some limitations.
|
||||
Before discussing virtual keyspaces and tables, note that virtual keyspaces and tables have some limitations.
|
||||
These limitations are subject to change.
|
||||
Virtual keyspaces cannot be altered or dropped.
|
||||
Virtual keyspaces cannot be altered or dropped.
|
||||
In fact, no operations can be performed against virtual keyspaces.
|
||||
|
||||
Virtual tables cannot be created in virtual keyspaces.
|
||||
|
|
@ -58,7 +57,7 @@ In fact, mutations for virtual and regular tables cannot occur in the same batch
|
|||
|
||||
Each of the virtual tables in the `system_views` virtual keyspace contain different information.
|
||||
|
||||
The following table describes the virtual tables:
|
||||
The following table describes the virtual tables:
|
||||
|
||||
[width="98%",cols="27%,73%",]
|
||||
|===
|
||||
|
|
@ -67,6 +66,10 @@ The following table describes the virtual tables:
|
|||
|caches |Displays the general cache information including cache name, capacity_bytes, entry_count, hit_count, hit_ratio double,
|
||||
recent_hit_rate_per_second, recent_request_rate_per_second, request_count, and size_bytes.
|
||||
|
||||
|cidr_filtering_metrics_counts |Counts metrics specific to CIDR filtering.
|
||||
|
||||
|cidr_filtering_metrics_latencies |Latencies metrics specific to CIDR filtering.
|
||||
|
||||
|clients |Lists information about all connected clients.
|
||||
|
||||
|coordinator_read_latency |Records counts, keyspace_name, table_name, max, median, and per_second for coordinator reads.
|
||||
|
|
@ -116,7 +119,8 @@ clients) including their ip address, port, client_options, connection stage, dri
|
|||
name, driver version, hostname, protocol version, request count, ssl
|
||||
enabled, ssl protocol and user name:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> EXPAND ON ;
|
||||
Now Expanded output is enabled
|
||||
cqlsh> SELECT * FROM system_views.clients;
|
||||
|
|
@ -186,7 +190,7 @@ cqlsh> SELECT * FROM system_views.clients;
|
|||
username | anonymous
|
||||
|
||||
(4 rows)
|
||||
....
|
||||
----
|
||||
|
||||
Some examples of how `clients` can be used are:
|
||||
|
||||
|
|
@ -200,7 +204,8 @@ The virtual tables may be described with `DESCRIBE` statement. The DDL
|
|||
listed however cannot be run to create a virtual table. As an example
|
||||
describe the `system_views.clients` virtual table:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> DESCRIBE TABLE system_views.clients;
|
||||
|
||||
/*
|
||||
|
|
@ -224,7 +229,7 @@ VIRTUAL TABLE system_views.clients (
|
|||
) WITH CLUSTERING ORDER BY (port ASC)
|
||||
AND comment = 'currently connected clients';
|
||||
*/
|
||||
....
|
||||
----
|
||||
|
||||
=== Caches Virtual Table
|
||||
|
||||
|
|
@ -232,7 +237,8 @@ The `caches` virtual table lists information about the caches. The four
|
|||
caches presently created are chunks, counters, keys and rows. A query on
|
||||
the `caches` virtual table returns the following details:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh:system_views> SELECT * FROM system_views.caches;
|
||||
name | capacity_bytes | entry_count | hit_count | hit_ratio | recent_hit_rate_per_second | recent_request_rate_per_second | request_count | size_bytes
|
||||
---------+----------------+-------------+-----------+-----------+----------------------------+--------------------------------+---------------+------------
|
||||
|
|
@ -242,7 +248,93 @@ counters | 26214400 | 0 | 0 | NaN |
|
|||
rows | 0 | 0 | 0 | NaN | 0 | 0 | 0 | 0
|
||||
|
||||
(4 rows)
|
||||
....
|
||||
----
|
||||
|
||||
=======
|
||||
=== CIDR filtering metrics Virtual Tables
|
||||
The `cidr_filtering_metrics_counts` virtual table lists counts metrics specific to CIDR filtering. A query on `cidr_filtering_metrics_counts` virtual table lists metrics similar to below.
|
||||
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> select * from system_views.cidr_filtering_metrics_counts;
|
||||
name | value
|
||||
--------------------------------------------------------+-------
|
||||
CIDR groups cache reload count | 2
|
||||
Number of CIDR accesses accepted from CIDR group - aws | 15
|
||||
Number of CIDR accesses accepted from CIDR group - gcp | 30
|
||||
Number of CIDR accesses rejected from CIDR group - gcp | 6
|
||||
----
|
||||
|
||||
The `cidr_filtering_metrics_latencies` virtual table lists latencies metrics specific to CIDR filtering. A query on `cidr_filtering_metrics_latencies` virtual table lists below metrics.
|
||||
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> select * from system_views.cidr_filtering_metrics_latencies;
|
||||
name | max | p50th | p95th | p999th | p99th
|
||||
---------------------------------------------+-------+-------+-------+--------+-------
|
||||
CIDR checks latency (ns) | 24601 | 1 | 11864 | 24601 | 24601
|
||||
CIDR groups cache reload latency (ns) | 42510 | 42510 | 42510 | 42510 | 42510
|
||||
Lookup IP in CIDR groups cache latency (ns) | 1 | 1 | 1 | 1 | 1
|
||||
----
|
||||
|
||||
=== CQL metrics Virtual Table
|
||||
|
||||
The `cql_metrics` virtual table lists metrics specific to CQL prepared statement caching. A query on `cql_metrics` virtual table lists below metrics.
|
||||
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> select * from system_views.cql_metrics ;
|
||||
|
||||
name | value
|
||||
------------------------------+-------
|
||||
prepared_statements_count | 0
|
||||
prepared_statements_evicted | 0
|
||||
prepared_statements_executed | 0
|
||||
prepared_statements_ratio | 0
|
||||
regular_statements_executed | 17
|
||||
----
|
||||
|
||||
=== CIDR filtering metrics Virtual Tables
|
||||
The `cidr_filtering_metrics_counts` virtual table lists counts metrics specific to CIDR filtering. A query on `cidr_filtering_metrics_counts` virtual table lists metrics similar to below.
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> select * from system_views.cidr_filtering_metrics_counts;
|
||||
name | value
|
||||
--------------------------------------------------------+-------
|
||||
CIDR groups cache reload count | 2
|
||||
Number of CIDR accesses accepted from CIDR group - aws | 15
|
||||
Number of CIDR accesses accepted from CIDR group - gcp | 30
|
||||
Number of CIDR accesses rejected from CIDR group - gcp | 6
|
||||
----
|
||||
|
||||
The `cidr_filtering_metrics_latencies` virtual table lists latencies metrics specific to CIDR filtering. A query on `cidr_filtering_metrics_latencies` virtual table lists below metrics.
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> select * from system_views.cidr_filtering_metrics_latencies;
|
||||
name | max | p50th | p95th | p999th | p99th
|
||||
---------------------------------------------+-------+-------+-------+--------+-------
|
||||
CIDR checks latency (ns) | 24601 | 1 | 11864 | 24601 | 24601
|
||||
CIDR groups cache reload latency (ns) | 42510 | 42510 | 42510 | 42510 | 42510
|
||||
Lookup IP in CIDR groups cache latency (ns) | 1 | 1 | 1 | 1 | 1
|
||||
----
|
||||
|
||||
=== CQL metrics Virtual Table
|
||||
The `cql_metrics` virtual table lists metrics specific to CQL prepared statement caching. A query on `cql_metrics` virtual table lists below metrics.
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> select * from system_views.cql_metrics ;
|
||||
|
||||
name | value
|
||||
------------------------------+-------
|
||||
prepared_statements_count | 0
|
||||
prepared_statements_evicted | 0
|
||||
prepared_statements_executed | 0
|
||||
prepared_statements_ratio | 0
|
||||
regular_statements_executed | 17
|
||||
----
|
||||
|
||||
=== Settings Virtual Table
|
||||
|
||||
|
|
@ -252,7 +344,8 @@ are overridden to hide the sensitive truststore information or
|
|||
passwords. The configuration settings however cannot be set using DML on
|
||||
the virtual table presently: :
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh:system_views> SELECT * FROM system_views.settings;
|
||||
|
||||
name | value
|
||||
|
|
@ -276,10 +369,10 @@ name | value
|
|||
storage_port | 7000
|
||||
stream_entire_sstables | true
|
||||
(224 rows)
|
||||
....
|
||||
----
|
||||
|
||||
The `settings` table can be really useful if yaml file has been changed
|
||||
since startup and dont know running configuration, or to find if they
|
||||
since startup and don't know running configuration, or to find if they
|
||||
have been modified via jmx/nodetool or virtual tables.
|
||||
|
||||
=== Thread Pools Virtual Table
|
||||
|
|
@ -289,7 +382,8 @@ Thread pool information includes active tasks, active tasks limit,
|
|||
blocked tasks, blocked tasks all time, completed tasks, and pending
|
||||
tasks. A query on the `thread_pools` returns following details:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh:system_views> select * from system_views.thread_pools;
|
||||
|
||||
name | active_tasks | active_tasks_limit | blocked_tasks | blocked_tasks_all_time | completed_tasks | pending_tasks
|
||||
|
|
@ -318,9 +412,9 @@ PerDiskMemtableFlushWriter_0 | 0 | 2 | 0
|
|||
ValidationExecutor | 0 | 2147483647 | 0 | 0 | 0 | 0
|
||||
ViewBuildExecutor | 0 | 1 | 0 | 0 | 0 | 0
|
||||
ViewMutationStage | 0 | 32 | 0 | 0 | 0 | 0
|
||||
....
|
||||
|
||||
(24 rows)
|
||||
----
|
||||
|
||||
=== Internode Inbound Messaging Virtual Table
|
||||
|
||||
|
|
@ -333,36 +427,38 @@ received bytes, received count, scheduled bytes, scheduled count,
|
|||
throttled count, throttled nanos, using bytes, using reserve bytes. A
|
||||
query on the `internode_inbound` returns following details:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh:system_views> SELECT * FROM system_views.internode_inbound;
|
||||
address | port | dc | rack | corrupt_frames_recovered | corrupt_frames_unrecovered |
|
||||
error_bytes | error_count | expired_bytes | expired_count | processed_bytes |
|
||||
processed_count | received_bytes | received_count | scheduled_bytes | scheduled_count | throttled_count | throttled_nanos | using_bytes | using_reserve_bytes
|
||||
---------+------+----+------+--------------------------+----------------------------+-
|
||||
----------
|
||||
(0 rows)
|
||||
....
|
||||
----
|
||||
|
||||
=== SSTables Tasks Virtual Table
|
||||
|
||||
The `sstable_tasks` could be used to get information about running
|
||||
tasks. It lists following columns:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh:system_views> SELECT * FROM sstable_tasks;
|
||||
keyspace_name | table_name | task_id | kind | progress | total | unit
|
||||
---------------+------------+--------------------------------------+------------+----------+----------+-------
|
||||
basic | wide2 | c3909740-cdf7-11e9-a8ed-0f03de2d9ae1 | compaction | 60418761 | 70882110 | bytes
|
||||
basic | wide2 | c7556770-cdf7-11e9-a8ed-0f03de2d9ae1 | compaction | 2995623 | 40314679 | bytes
|
||||
....
|
||||
----
|
||||
|
||||
As another example, to find how much time is remaining for SSTable
|
||||
tasks, use the following query:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
SELECT total - progress AS remaining
|
||||
FROM system_views.sstable_tasks;
|
||||
....
|
||||
----
|
||||
|
||||
=== Other Virtual Tables
|
||||
|
||||
|
|
@ -370,49 +466,48 @@ Some examples of using other virtual tables are as follows.
|
|||
|
||||
Find tables with most disk usage:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> SELECT * FROM disk_usage WHERE mebibytes > 1 ALLOW FILTERING;
|
||||
|
||||
keyspace_name | table_name | mebibytes
|
||||
---------------+------------+-----------
|
||||
keyspace1 | standard1 | 288
|
||||
tlp_stress | keyvalue | 3211
|
||||
....
|
||||
----
|
||||
|
||||
Find queries on table/s with greatest read latency:
|
||||
|
||||
....
|
||||
[source, console]
|
||||
----
|
||||
cqlsh> SELECT * FROM local_read_latency WHERE per_second > 1 ALLOW FILTERING;
|
||||
|
||||
keyspace_name | table_name | p50th_ms | p99th_ms | count | max_ms | per_second
|
||||
---------------+------------+----------+----------+----------+---------+------------
|
||||
tlp_stress | keyvalue | 0.043 | 0.152 | 49785158 | 186.563 | 11418.356
|
||||
....
|
||||
----
|
||||
|
||||
|
||||
== Example
|
||||
|
||||
[arabic, start=1]
|
||||
. To list the keyspaces, enter ``cqlsh`` and run the CQL command ``DESCRIBE KEYSPACES``:
|
||||
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> DESC KEYSPACES;
|
||||
system_schema system system_distributed system_virtual_schema
|
||||
system_auth system_traces system_views
|
||||
----
|
||||
|
||||
[arabic, start=2]
|
||||
. To view the virtual table schema, run the CQL commands ``USE system_virtual_schema`` and ``SELECT * FROM tables``:
|
||||
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> USE system_virtual_schema;
|
||||
cqlsh> SELECT * FROM tables;
|
||||
----
|
||||
|
||||
+
|
||||
results in:
|
||||
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
keyspace_name | table_name | comment
|
||||
|
|
@ -441,18 +536,16 @@ results in:
|
|||
|
||||
(21 rows)
|
||||
----
|
||||
|
||||
[arabic, start=3]
|
||||
. To view the virtual tables, run the CQL commands ``USE system_view`` and ``DESCRIBE tables``:
|
||||
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> USE system_view;;
|
||||
cqlsh> DESCRIBE tables;
|
||||
----
|
||||
|
||||
+
|
||||
results in:
|
||||
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
sstable_tasks clients coordinator_write_latency
|
||||
|
|
@ -462,23 +555,22 @@ local_scan_latency coordinator_scan_latency system_properties
|
|||
internode_inbound coordinator_read_latency max_partition_size
|
||||
local_read_latency rows_per_read caches
|
||||
----
|
||||
|
||||
[arabic, start=4]
|
||||
. To look at any table data, run the CQL command ``SELECT``:
|
||||
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> USE system_view;;
|
||||
cqlsh> SELECT * FROM clients LIMIT 2;
|
||||
----
|
||||
results in:
|
||||
|
||||
+
|
||||
results in:
|
||||
+
|
||||
[source, cql]
|
||||
----
|
||||
address | port | connection_stage | driver_name | driver_version | hostname | protocol_version | request_count | ssl_cipher_suite | ssl_enabled | ssl_protocol | username
|
||||
-----------+-------+------------------+------------------------+----------------+-----------+------------------+---------------+------------------+-------------+--------------+-----------
|
||||
-----------+-------+------------------+------------------------+----------------+-----------|||+------------------+---------------+------------------+-------------+--------------+-----------
|
||||
127.0.0.1 | 37308 | ready | DataStax Python Driver | 3.21.0.post0 | localhost | 4 | 17 | null | False | null | anonymous
|
||||
127.0.0.1 | 37310 | ready | DataStax Python Driver | 3.21.0.post0 | localhost | 4 | 8 | null | False | null | anonymous
|
||||
|
||||
(2 rows)
|
||||
----
|
||||
----
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
= cqlsh: the CQL shell
|
||||
|
||||
`cqlsh` is a command-line interface for interacting with Cassandra using CQL (the Cassandra Query Language).
|
||||
`cqlsh` is a command-line interface for interacting with Cassandra using CQL (the Cassandra Query Language).
|
||||
It is shipped with every Cassandra package, and can be found in the bin/ directory alongside the cassandra
|
||||
executable.
|
||||
executable.
|
||||
`cqlsh` is implemented with the Python native protocol driver, and connects to the single specified node.
|
||||
|
||||
== Compatibility
|
||||
|
||||
In general, a given version of `cqlsh` is only guaranteed to work with the
|
||||
version of Cassandra that it was released with.
|
||||
version of Cassandra that it was released with.
|
||||
In some cases, `cqlsh` may work with older or newer versions of Cassandra, but this is not
|
||||
officially supported.
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ of `cqlsh`.
|
|||
|
||||
By default, `cqlsh` displays all timestamps with a UTC timezone.
|
||||
For Python 3.9 or higher, timestamps can be displayed in different timezones by modifying the
|
||||
`timezone` option in xref:cql/tools/cqlsh.adoc#cqlshrc[cqlshrc] or by setting the environment
|
||||
`timezone` option in xref:cassandra:developing/cql/tools/cqlsh.adoc#cqlshrc[cqlshrc] or by setting the environment
|
||||
variable `TZ`.
|
||||
Python 3.8 or lower, however, will also require the installation of http://pytz.sourceforge.net/[pytz] library.
|
||||
|
||||
|
|
@ -35,12 +35,12 @@ modules that are central to the performance of `COPY`.
|
|||
[[cqlshrc]]
|
||||
== cqlshrc
|
||||
|
||||
The `cqlshrc` file holds configuration options for `cqlsh`.
|
||||
The `cqlshrc` file holds configuration options for `cqlsh`.
|
||||
By default, the file is located the user's home directory at `~/.cassandra/cqlshrc`, but a
|
||||
custom location can be specified with the `--cqlshrc` option.
|
||||
|
||||
Example config values and documentation can be found in the
|
||||
`conf/cqlshrc.sample` file of a tarball installation.
|
||||
`conf/cqlshrc.sample` file of a tarball installation.
|
||||
You can also view the latest version of the
|
||||
https://github.com/apache/cassandra/blob/trunk/conf/cqlshrc.sample[cqlshrc file online].
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
This section describes the command line tools provided with Apache
|
||||
Cassandra.
|
||||
|
||||
* xref:tools/cqlsh.adoc[CQL shell]
|
||||
* xref:tools/nodetool/nodetool.adoc[nodetool]
|
||||
* xref:tools/sstable/index.adoc[SSTable tools]
|
||||
* xref:tools/cassandra_stress.adoc[cassandra-stress tool]
|
||||
* xref:tools/hash_password.adoc[hash password tool]
|
||||
* xref:cassandra:managing/tools/cqlsh.adoc[CQL shell]
|
||||
* xref:cassandra:managing/tools/nodetool/nodetool.adoc[nodetool]
|
||||
* xref:cassandra:managing/tools/sstable/index.adoc[SSTable tools]
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
= SSTable Tools
|
||||
|
||||
This section describes the functionality of the various sstable tools.
|
||||
This section describes the functionality of the various `sstable` tools.
|
||||
|
||||
Cassandra must be stopped before these tools are executed, or unexpected
|
||||
results will occur. Note: the scripts do not verify that Cassandra is
|
||||
stopped.
|
||||
|
||||
* xref:tools/sstable/sstabledump.adoc[sstabledump]
|
||||
* xref:tools/sstable/sstableexpiredblockers.adoc[sstableexpiredblockers]
|
||||
* xref:tools/sstable/sstablelevelreset.adoc[sstablelevelreset]
|
||||
* xref:tools/sstable/sstableloader.adoc[sstableloader]
|
||||
* xref:tools/sstable/sstablemetadata.adoc[sstablemetadata]
|
||||
* xref:tools/sstable/sstableofflinerelevel.adoc[sstableofflinerelevel]
|
||||
* xref:tools/sstable/sstablepartitions.adoc[sstablepartitions]
|
||||
* xref:tools/sstable/sstablerepairedset.adoc[sstablerepairdset]
|
||||
* xref:tools/sstable/sstablescrub.adoc[sstablescrub]
|
||||
* xref:tools/sstable/sstablesplit.adoc[sstablesplit]
|
||||
* xref:tools/sstable/sstableupgrade.adoc[sstableupgrade]
|
||||
* xref:tools/sstable/sstableutil.adoc[sstableutil]
|
||||
* xref:tools/sstable/sstableverify.adoc[sstableverify]
|
||||
* xref:cassandra:managing/tools/sstable/sstabledump.adoc[sstabledump]
|
||||
* xref:cassandra:managing/tools/sstable/sstableexpiredblockers.adoc[sstableexpiredblockers]
|
||||
* xref:cassandra:managing/tools/sstable/sstablelevelreset.adoc[sstablelevelreset]
|
||||
* xref:cassandra:managing/tools/sstable/sstableloader.adoc[sstableloader]
|
||||
* xref:cassandra:managing/tools/sstable/sstablemetadata.adoc[sstablemetadata]
|
||||
* xref:cassandra:managing/tools/sstable/sstableofflinerelevel.adoc[sstableofflinerelevel]
|
||||
* xref:cassandra:managing/tools/sstable/sstablepartitions.adoc[sstablepartitions]
|
||||
* xref:cassandra:managing/tools/sstable/sstablerepairedset.adoc[sstablerepairdset]
|
||||
* xref:cassandra:managing/tools/sstable/sstablescrub.adoc[sstablescrub]
|
||||
* xref:cassandra:managing/tools/sstable/sstablesplit.adoc[sstablesplit]
|
||||
* xref:cassandra:managing/tools/sstable/sstableupgrade.adoc[sstableupgrade]
|
||||
* xref:cassandra:managing/tools/sstable/sstableutil.adoc[sstableutil]
|
||||
* xref:cassandra:managing/tools/sstable/sstableverify.adoc[sstableverify]
|
||||
|
|
|
|||
|
|
@ -251,15 +251,15 @@ Estimated tombstone drop times:
|
|||
$ echo $(date +%s)
|
||||
1536602005
|
||||
|
||||
# if gc_grace_seconds was configured at 100, all of the tombstones would be currently droppable
|
||||
# if gc_grace_seconds was configured at 100, all of the tombstones would be currently droppable
|
||||
$ sstablemetadata --gc_grace_seconds 100 /var/lib/cassandra/data/keyspace1/standard1-41b52700b4ed11e896476d2c86545d91/mc-12-big-Data.db | grep "Estimated droppable tombstones"
|
||||
Estimated droppable tombstones: 4.0E-5
|
||||
|
||||
# if gc_grace_seconds was configured at 4700, some of the tombstones would be currently droppable
|
||||
# if gc_grace_seconds was configured at 4700, some of the tombstones would be currently droppable
|
||||
$ sstablemetadata --gc_grace_seconds 4700 /var/lib/cassandra/data/keyspace1/standard1-41b52700b4ed11e896476d2c86545d91/mc-12-big-Data.db | grep "Estimated droppable tombstones"
|
||||
Estimated droppable tombstones: 9.61111111111111E-6
|
||||
|
||||
# if gc_grace_seconds was configured at 100, none of the tombstones would be currently droppable
|
||||
# if gc_grace_seconds was configured at 100, none of the tombstones would be currently droppable
|
||||
$ sstablemetadata --gc_grace_seconds 5000 /var/lib/cassandra/data/keyspace1/standard1-41b52700b4ed11e896476d2c86545d91/mc-12-big-Data.db | grep "Estimated droppable tombstones"
|
||||
Estimated droppable tombstones: 0.0
|
||||
....
|
||||
|
|
@ -298,57 +298,57 @@ Largest Partitions:
|
|||
|
||||
|SSTable |prefix of the sstable filenames related to this sstable
|
||||
|Partitioner |partitioner type used to distribute data across nodes;
|
||||
defined in cassandra.yaml
|
||||
defined in cassandra.yaml
|
||||
|Bloom Filter FP |precision of Bloom filter used
|
||||
in reads; defined in the table definition
|
||||
in reads; defined in the table definition
|
||||
|Minimum timestamp |minimum
|
||||
timestamp of any entry in this sstable, in epoch microseconds
|
||||
timestamp of any entry in this sstable, in epoch microseconds
|
||||
|Maximum
|
||||
timestamp |maximum timestamp of any entry in this sstable, in epoch
|
||||
microseconds
|
||||
|Duration |Difference between Maximum timestamp and Minimum timestamp
|
||||
|SSTable min local deletion time |minimum timestamp of
|
||||
deletion date, based on TTL, in epoch seconds
|
||||
deletion date, based on TTL, in epoch seconds
|
||||
|SSTable max local deletion
|
||||
time |maximum timestamp of deletion date, based on TTL, in epoch seconds
|
||||
|Compressor |blank (-) by default; if not blank, indicates type of
|
||||
compression enabled on the table
|
||||
compression enabled on the table
|
||||
|TTL min |time-to-live in seconds;
|
||||
default 0 unless defined in the table definition
|
||||
default 0 unless defined in the table definition
|
||||
|TTL max |time-to-live in
|
||||
seconds; default 0 unless defined in the table definition
|
||||
|First token |lowest token and related key found in the sstable summary
|
||||
|Last token |highest token and related key found in the sstable summary
|
||||
seconds; default 0 unless defined in the table definition
|
||||
|First token |lowest token and related key found in the sstable summary
|
||||
|Last token |highest token and related key found in the sstable summary
|
||||
|Estimated
|
||||
droppable tombstones |ratio of tombstones to columns, using configured gc
|
||||
grace seconds if relevant
|
||||
grace seconds if relevant
|
||||
|SSTable level |compaction level of this
|
||||
sstable, if leveled compaction (LCS) is used
|
||||
sstable, if leveled compaction (LCS) is used
|
||||
|Repaired at |the timestamp
|
||||
this sstable was marked as repaired via sstablerepairedset, in epoch
|
||||
milliseconds
|
||||
milliseconds
|
||||
|Replay positions covered |the interval of time and commitlog
|
||||
positions related to this sstable
|
||||
|totalColumnsSet |number of cells in the table
|
||||
|totalRows |number of rows in the table
|
||||
|Estimated tombstone drop
|
||||
times |approximate number of rows that will expire, ordered by epoch
|
||||
seconds
|
||||
seconds
|
||||
|Count Row Size Cell Count |two histograms in two columns; one
|
||||
represents distribution of Row Size and the other represents
|
||||
distribution of Cell Count
|
||||
distribution of Cell Count
|
||||
|Estimated cardinality an estimate of unique
|
||||
values, used for compaction
|
||||
values, used for compaction
|
||||
|EncodingStats* minTTL |in epoch milliseconds
|
||||
|EncodingStats* minLocalDeletionTime |in epoch seconds
|
||||
|EncodingStats* minLocalDeletionTime |in epoch seconds
|
||||
|EncodingStats*
|
||||
minTimestamp |in epoch microseconds
|
||||
minTimestamp |in epoch microseconds
|
||||
|KeyType |the type of partition key,
|
||||
useful in reading and writing data from/to storage; defined in the table
|
||||
definition
|
||||
definition
|
||||
|ClusteringTypes |the type of clustering key, useful in reading
|
||||
and writing data from/to storage; defined in the table definition
|
||||
|StaticColumns |a list of the shared columns in the table
|
||||
|StaticColumns |a list of the shared columns in the table
|
||||
|RegularColumns |a
|
||||
list of non-static, non-key columns in the table
|
||||
|===
|
||||
|
|
|
|||
|
|
@ -1,546 +0,0 @@
|
|||
= Virtual Tables
|
||||
|
||||
Apache Cassandra 4.0 implements virtual tables (https://issues.apache.org/jira/browse/CASSANDRA-7622[CASSANDRA-7622]).
|
||||
Virtual tables are tables backed by an API instead of data explicitly managed and stored as SSTables.
|
||||
Apache Cassandra 4.0 implements a virtual keyspace interface for virtual tables.
|
||||
Virtual tables are specific to each node.
|
||||
|
||||
Some of the features of virtual tables are the ability to:
|
||||
|
||||
* expose metrics through CQL
|
||||
* expose YAML configuration information
|
||||
|
||||
Virtual keyspaces and tables are quite different from regular tables and keyspaces:
|
||||
|
||||
* Virtual tables are created in special keyspaces and not just any keyspace.
|
||||
* Virtual tables are managed by Cassandra. Users cannot run DDL to create new virtual tables or DML to modify existing virtual tables.
|
||||
* Virtual tables are currently read-only, although that may change in a later version.
|
||||
* Virtual tables are local only, non-distributed, and thus not replicated.
|
||||
* Virtual tables have no associated SSTables.
|
||||
* Consistency level of the queries sent to virtual tables are ignored.
|
||||
* All existing virtual tables use `LocalPartitioner`.
|
||||
Since a virtual table is not replicated the partitioner sorts in order of partition keys instead of by their hash.
|
||||
* Making advanced queries using `ALLOW FILTERING` and aggregation functions can be executed in virtual tables, even though in normal tables we dont recommend it.
|
||||
|
||||
== Virtual Keyspaces
|
||||
|
||||
Apache Cassandra 4.0 has added two new keyspaces for virtual tables:
|
||||
|
||||
* `system_virtual_schema`
|
||||
* `system_views`.
|
||||
|
||||
The `system_virtual_schema` keyspace has three tables: `keyspaces`,
|
||||
`columns` and `tables` for the virtual keyspace, table, and column definitions, respectively.
|
||||
These tables contain schema information for the virtual tables.
|
||||
It is used by Cassandra internally and a user should not access it directly.
|
||||
|
||||
The `system_views` keyspace contains the actual virtual tables.
|
||||
|
||||
== Virtual Table Limitations
|
||||
|
||||
Before disccusing virtual keyspaces and tables, note that virtual keyspaces and tables have some limitations.
|
||||
These limitations are subject to change.
|
||||
Virtual keyspaces cannot be altered or dropped.
|
||||
In fact, no operations can be performed against virtual keyspaces.
|
||||
|
||||
Virtual tables cannot be created in virtual keyspaces.
|
||||
Virtual tables cannot be altered, dropped, or truncated.
|
||||
Secondary indexes, types, functions, aggregates, materialized views, and triggers cannot be created for virtual tables.
|
||||
Expiring time-to-live (TTL) columns cannot be created.
|
||||
Virtual tables do not support conditional updates or deletes.
|
||||
Aggregates may be run in SELECT statements.
|
||||
|
||||
Conditional batch statements cannot include mutations for virtual tables, nor can a virtual table statement be included in a logged batch.
|
||||
In fact, mutations for virtual and regular tables cannot occur in the same batch table.
|
||||
|
||||
== Virtual Tables
|
||||
|
||||
Each of the virtual tables in the `system_views` virtual keyspace contain different information.
|
||||
|
||||
The following table describes the virtual tables:
|
||||
|
||||
[width="98%",cols="27%,73%",]
|
||||
|===
|
||||
|Virtual Table |Description
|
||||
|
||||
|caches |Displays the general cache information including cache name, capacity_bytes, entry_count, hit_count, hit_ratio double,
|
||||
recent_hit_rate_per_second, recent_request_rate_per_second, request_count, and size_bytes.
|
||||
|
||||
|cidr_filtering_metrics_counts |Counts metrics specific to CIDR filtering.
|
||||
|
||||
|cidr_filtering_metrics_latencies |Latencies metrics specific to CIDR filtering.
|
||||
|
||||
|clients |Lists information about all connected clients.
|
||||
|
||||
|coordinator_read_latency |Records counts, keyspace_name, table_name, max, median, and per_second for coordinator reads.
|
||||
|
||||
|coordinator_scan |Records counts, keyspace_name, table_name, max, median, and per_second for coordinator scans.
|
||||
|
||||
|coordinator_write_latency |Records counts, keyspace_name, table_name, max, median, and per_second for coordinator writes.
|
||||
|
||||
|cql_metrics |Metrics specific to CQL prepared statement caching.
|
||||
|
||||
|disk_usage |Records disk usage including disk_space, keyspace_name, and table_name, sorted by system keyspaces.
|
||||
|
||||
|gossip_info |Lists the gossip information for the cluster.
|
||||
|
||||
|internode_inbound |Lists information about the inbound internode messaging.
|
||||
|
||||
|internode_outbound |Information about the outbound internode messaging.
|
||||
|
||||
|local_read_latency |Records counts, keyspace_name, table_name, max, median, and per_second for local reads.
|
||||
|
||||
|local_scan |Records counts, keyspace_name, table_name, max, median, and per_second for local scans.
|
||||
|
||||
|local_write_latency |Records counts, keyspace_name, table_name, max, median, and per_second for local writes.
|
||||
|
||||
|max_partition_size |A table metric for maximum partition size.
|
||||
|
||||
|rows_per_read |Records counts, keyspace_name, tablek_name, max, and median for rows read.
|
||||
|
||||
|settings |Displays configuration settings in cassandra.yaml.
|
||||
|
||||
|sstable_tasks |Lists currently running tasks and progress on SSTables, for operations like compaction and upgrade.
|
||||
|
||||
|system_properties |Displays environmental system properties set on the node.
|
||||
|
||||
|thread_pools |Lists metrics for each thread pool.
|
||||
|
||||
|tombstones_per_read |Records counts, keyspace_name, tablek_name, max, and median for tombstones.
|
||||
|
||||
|===
|
||||
|
||||
We shall discuss some of the virtual tables in more detail next.
|
||||
|
||||
=== Clients Virtual Table
|
||||
|
||||
The `clients` virtual table lists all active connections (connected
|
||||
clients) including their ip address, port, client_options, connection stage, driver
|
||||
name, driver version, hostname, protocol version, request count, ssl
|
||||
enabled, ssl protocol and user name:
|
||||
|
||||
....
|
||||
cqlsh> EXPAND ON ;
|
||||
Now Expanded output is enabled
|
||||
cqlsh> SELECT * FROM system_views.clients;
|
||||
|
||||
@ Row 1
|
||||
------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
address | 127.0.0.1
|
||||
port | 50687
|
||||
client_options | {'CQL_VERSION': '3.4.7', 'DRIVER_NAME': 'DataStax Python Driver', 'DRIVER_VERSION': '3.25.0'}
|
||||
connection_stage | ready
|
||||
driver_name | DataStax Python Driver
|
||||
driver_version | 3.25.0
|
||||
hostname | localhost
|
||||
protocol_version | 5
|
||||
request_count | 16
|
||||
ssl_cipher_suite | null
|
||||
ssl_enabled | False
|
||||
ssl_protocol | null
|
||||
username | anonymous
|
||||
|
||||
@ Row 2
|
||||
------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
address | 127.0.0.1
|
||||
port | 50688
|
||||
client_options | {'CQL_VERSION': '3.4.7', 'DRIVER_NAME': 'DataStax Python Driver', 'DRIVER_VERSION': '3.25.0'}
|
||||
connection_stage | ready
|
||||
driver_name | DataStax Python Driver
|
||||
driver_version | 3.25.0
|
||||
hostname | localhost
|
||||
protocol_version | 5
|
||||
request_count | 4
|
||||
ssl_cipher_suite | null
|
||||
ssl_enabled | False
|
||||
ssl_protocol | null
|
||||
username | anonymous
|
||||
|
||||
@ Row 3
|
||||
------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
address | 127.0.0.1
|
||||
port | 50753
|
||||
client_options | {'APPLICATION_NAME': 'TestApp', 'APPLICATION_VERSION': '1.0.0', 'CLIENT_ID': '55b3efbd-c56b-469d-8cca-016b860b2f03', 'CQL_VERSION': '3.0.0', 'DRIVER_NAME': 'DataStax Java driver for Apache Cassandra(R)', 'DRIVER_VERSION': '4.13.0'}
|
||||
connection_stage | ready
|
||||
driver_name | DataStax Java driver for Apache Cassandra(R)
|
||||
driver_version | 4.13.0
|
||||
hostname | localhost
|
||||
protocol_version | 5
|
||||
request_count | 18
|
||||
ssl_cipher_suite | null
|
||||
ssl_enabled | False
|
||||
ssl_protocol | null
|
||||
username | anonymous
|
||||
|
||||
@ Row 4
|
||||
------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
address | 127.0.0.1
|
||||
port | 50755
|
||||
client_options | {'APPLICATION_NAME': 'TestApp', 'APPLICATION_VERSION': '1.0.0', 'CLIENT_ID': '55b3efbd-c56b-469d-8cca-016b860b2f03', 'CQL_VERSION': '3.0.0', 'DRIVER_NAME': 'DataStax Java driver for Apache Cassandra(R)', 'DRIVER_VERSION': '4.13.0'}
|
||||
connection_stage | ready
|
||||
driver_name | DataStax Java driver for Apache Cassandra(R)
|
||||
driver_version | 4.13.0
|
||||
hostname | localhost
|
||||
protocol_version | 5
|
||||
request_count | 7
|
||||
ssl_cipher_suite | null
|
||||
ssl_enabled | False
|
||||
ssl_protocol | null
|
||||
username | anonymous
|
||||
|
||||
(4 rows)
|
||||
....
|
||||
|
||||
Some examples of how `clients` can be used are:
|
||||
|
||||
* To find applications using old incompatible versions of drivers before
|
||||
upgrading and with `nodetool enableoldprotocolversions` and
|
||||
`nodetool disableoldprotocolversions` during upgrades.
|
||||
* To identify clients sending too many requests.
|
||||
* To find if SSL is enabled during the migration to and from ssl.
|
||||
* To identify all options the client is sending, e.g. APPLICATION_NAME and APPLICATION_VERSION
|
||||
|
||||
The virtual tables may be described with `DESCRIBE` statement. The DDL
|
||||
listed however cannot be run to create a virtual table. As an example
|
||||
describe the `system_views.clients` virtual table:
|
||||
|
||||
....
|
||||
cqlsh> DESCRIBE TABLE system_views.clients;
|
||||
|
||||
/*
|
||||
Warning: Table system_views.clients is a virtual table and cannot be recreated with CQL.
|
||||
Structure, for reference:
|
||||
VIRTUAL TABLE system_views.clients (
|
||||
address inet,
|
||||
port int,
|
||||
client_options frozen<map<text, text>>,
|
||||
connection_stage text,
|
||||
driver_name text,
|
||||
driver_version text,
|
||||
hostname text,
|
||||
protocol_version int,
|
||||
request_count bigint,
|
||||
ssl_cipher_suite text,
|
||||
ssl_enabled boolean,
|
||||
ssl_protocol text,
|
||||
username text,
|
||||
PRIMARY KEY (address, port)
|
||||
) WITH CLUSTERING ORDER BY (port ASC)
|
||||
AND comment = 'currently connected clients';
|
||||
*/
|
||||
....
|
||||
|
||||
=== Caches Virtual Table
|
||||
|
||||
The `caches` virtual table lists information about the caches. The four
|
||||
caches presently created are chunks, counters, keys and rows. A query on
|
||||
the `caches` virtual table returns the following details:
|
||||
|
||||
....
|
||||
cqlsh:system_views> SELECT * FROM system_views.caches;
|
||||
name | capacity_bytes | entry_count | hit_count | hit_ratio | recent_hit_rate_per_second | recent_request_rate_per_second | request_count | size_bytes
|
||||
---------+----------------+-------------+-----------+-----------+----------------------------+--------------------------------+---------------+------------
|
||||
chunks | 229638144 | 29 | 166 | 0.83 | 5 | 6 | 200 | 475136
|
||||
counters | 26214400 | 0 | 0 | NaN | 0 | 0 | 0 | 0
|
||||
keys | 52428800 | 14 | 124 | 0.873239 | 4 | 4 | 142 | 1248
|
||||
rows | 0 | 0 | 0 | NaN | 0 | 0 | 0 | 0
|
||||
|
||||
(4 rows)
|
||||
....
|
||||
|
||||
|
||||
=== CIDR filtering metrics Virtual Tables
|
||||
The `cidr_filtering_metrics_counts` virtual table lists counts metrics specific to CIDR filtering. A query on `cidr_filtering_metrics_counts` virtual table lists metrics similar to below.
|
||||
|
||||
....
|
||||
cqlsh> select * from system_views.cidr_filtering_metrics_counts;
|
||||
name | value
|
||||
--------------------------------------------------------+-------
|
||||
CIDR groups cache reload count | 2
|
||||
Number of CIDR accesses accepted from CIDR group - aws | 15
|
||||
Number of CIDR accesses accepted from CIDR group - gcp | 30
|
||||
Number of CIDR accesses rejected from CIDR group - gcp | 6
|
||||
....
|
||||
|
||||
The `cidr_filtering_metrics_latencies` virtual table lists latencies metrics specific to CIDR filtering. A query on `cidr_filtering_metrics_latencies` virtual table lists below metrics.
|
||||
|
||||
....
|
||||
cqlsh> select * from system_views.cidr_filtering_metrics_latencies;
|
||||
name | max | p50th | p95th | p999th | p99th
|
||||
---------------------------------------------+-------+-------+-------+--------+-------
|
||||
CIDR checks latency (ns) | 24601 | 1 | 11864 | 24601 | 24601
|
||||
CIDR groups cache reload latency (ns) | 42510 | 42510 | 42510 | 42510 | 42510
|
||||
Lookup IP in CIDR groups cache latency (ns) | 1 | 1 | 1 | 1 | 1
|
||||
....
|
||||
|
||||
=== CQL metrics Virtual Table
|
||||
The `cql_metrics` virtual table lists metrics specific to CQL prepared statement caching. A query on `cql_metrics` virtual table lists below metrics.
|
||||
|
||||
....
|
||||
cqlsh> select * from system_views.cql_metrics ;
|
||||
|
||||
name | value
|
||||
------------------------------+-------
|
||||
prepared_statements_count | 0
|
||||
prepared_statements_evicted | 0
|
||||
prepared_statements_executed | 0
|
||||
prepared_statements_ratio | 0
|
||||
regular_statements_executed | 17
|
||||
....
|
||||
|
||||
=== Settings Virtual Table
|
||||
|
||||
The `settings` table is rather useful and lists all the current
|
||||
configuration settings from the `cassandra.yaml`. The encryption options
|
||||
are overridden to hide the sensitive truststore information or
|
||||
passwords. The configuration settings however cannot be set using DML on
|
||||
the virtual table presently: :
|
||||
|
||||
....
|
||||
cqlsh:system_views> SELECT * FROM system_views.settings;
|
||||
|
||||
name | value
|
||||
-------------------------------------+--------------------
|
||||
allocate_tokens_for_keyspace | null
|
||||
audit_logging_options_enabled | false
|
||||
auto_snapshot | true
|
||||
automatic_sstable_upgrade | false
|
||||
cluster_name | Test Cluster
|
||||
transient_replication_enabled | false
|
||||
hinted_handoff_enabled | true
|
||||
hints_directory | /home/ec2-user/cassandra/data/hints
|
||||
incremental_backups | false
|
||||
initial_token | null
|
||||
...
|
||||
...
|
||||
...
|
||||
rpc_address | localhost
|
||||
ssl_storage_port | 7001
|
||||
start_native_transport | true
|
||||
storage_port | 7000
|
||||
stream_entire_sstables | true
|
||||
(224 rows)
|
||||
....
|
||||
|
||||
The `settings` table can be really useful if yaml file has been changed
|
||||
since startup and dont know running configuration, or to find if they
|
||||
have been modified via jmx/nodetool or virtual tables.
|
||||
|
||||
=== Thread Pools Virtual Table
|
||||
|
||||
The `thread_pools` table lists information about all thread pools.
|
||||
Thread pool information includes active tasks, active tasks limit,
|
||||
blocked tasks, blocked tasks all time, completed tasks, and pending
|
||||
tasks. A query on the `thread_pools` returns following details:
|
||||
|
||||
....
|
||||
cqlsh:system_views> select * from system_views.thread_pools;
|
||||
|
||||
name | active_tasks | active_tasks_limit | blocked_tasks | blocked_tasks_all_time | completed_tasks | pending_tasks
|
||||
------------------------------+--------------+--------------------+---------------+------------------------+-----------------+---------------
|
||||
AntiEntropyStage | 0 | 1 | 0 | 0 | 0 | 0
|
||||
CacheCleanupExecutor | 0 | 1 | 0 | 0 | 0 | 0
|
||||
CompactionExecutor | 0 | 2 | 0 | 0 | 881 | 0
|
||||
CounterMutationStage | 0 | 32 | 0 | 0 | 0 | 0
|
||||
GossipStage | 0 | 1 | 0 | 0 | 0 | 0
|
||||
HintsDispatcher | 0 | 2 | 0 | 0 | 0 | 0
|
||||
InternalResponseStage | 0 | 2 | 0 | 0 | 0 | 0
|
||||
MemtableFlushWriter | 0 | 2 | 0 | 0 | 1 | 0
|
||||
MemtablePostFlush | 0 | 1 | 0 | 0 | 2 | 0
|
||||
MemtableReclaimMemory | 0 | 1 | 0 | 0 | 1 | 0
|
||||
MigrationStage | 0 | 1 | 0 | 0 | 0 | 0
|
||||
MiscStage | 0 | 1 | 0 | 0 | 0 | 0
|
||||
MutationStage | 0 | 32 | 0 | 0 | 0 | 0
|
||||
Native-Transport-Requests | 1 | 128 | 0 | 0 | 130 | 0
|
||||
PendingRangeCalculator | 0 | 1 | 0 | 0 | 1 | 0
|
||||
PerDiskMemtableFlushWriter_0 | 0 | 2 | 0 | 0 | 1 | 0
|
||||
ReadStage | 0 | 32 | 0 | 0 | 13 | 0
|
||||
Repair-Task | 0 | 2147483647 | 0 | 0 | 0 | 0
|
||||
RequestResponseStage | 0 | 2 | 0 | 0 | 0 | 0
|
||||
Sampler | 0 | 1 | 0 | 0 | 0 | 0
|
||||
SecondaryIndexManagement | 0 | 1 | 0 | 0 | 0 | 0
|
||||
ValidationExecutor | 0 | 2147483647 | 0 | 0 | 0 | 0
|
||||
ViewBuildExecutor | 0 | 1 | 0 | 0 | 0 | 0
|
||||
ViewMutationStage | 0 | 32 | 0 | 0 | 0 | 0
|
||||
....
|
||||
|
||||
(24 rows)
|
||||
|
||||
=== Internode Inbound Messaging Virtual Table
|
||||
|
||||
The `internode_inbound` virtual table is for the internode inbound
|
||||
messaging. Initially no internode inbound messaging may get listed. In
|
||||
addition to the address, port, datacenter and rack information includes
|
||||
corrupt frames recovered, corrupt frames unrecovered, error bytes, error
|
||||
count, expired bytes, expired count, processed bytes, processed count,
|
||||
received bytes, received count, scheduled bytes, scheduled count,
|
||||
throttled count, throttled nanos, using bytes, using reserve bytes. A
|
||||
query on the `internode_inbound` returns following details:
|
||||
|
||||
....
|
||||
cqlsh:system_views> SELECT * FROM system_views.internode_inbound;
|
||||
address | port | dc | rack | corrupt_frames_recovered | corrupt_frames_unrecovered |
|
||||
error_bytes | error_count | expired_bytes | expired_count | processed_bytes |
|
||||
processed_count | received_bytes | received_count | scheduled_bytes | scheduled_count | throttled_count | throttled_nanos | using_bytes | using_reserve_bytes
|
||||
---------+------+----+------+--------------------------+----------------------------+-
|
||||
----------
|
||||
(0 rows)
|
||||
....
|
||||
|
||||
=== SSTables Tasks Virtual Table
|
||||
|
||||
The `sstable_tasks` could be used to get information about running
|
||||
tasks. It lists following columns:
|
||||
|
||||
....
|
||||
cqlsh:system_views> SELECT * FROM sstable_tasks;
|
||||
keyspace_name | table_name | task_id | kind | progress | total | unit
|
||||
---------------+------------+--------------------------------------+------------+----------+----------+-------
|
||||
basic | wide2 | c3909740-cdf7-11e9-a8ed-0f03de2d9ae1 | compaction | 60418761 | 70882110 | bytes
|
||||
basic | wide2 | c7556770-cdf7-11e9-a8ed-0f03de2d9ae1 | compaction | 2995623 | 40314679 | bytes
|
||||
....
|
||||
|
||||
As another example, to find how much time is remaining for SSTable
|
||||
tasks, use the following query:
|
||||
|
||||
....
|
||||
SELECT total - progress AS remaining
|
||||
FROM system_views.sstable_tasks;
|
||||
....
|
||||
|
||||
=== Gossip Information Virtual Table
|
||||
|
||||
The `gossip_info` virtual table lists the Gossip information for the cluster. An example query is as follows:
|
||||
|
||||
....
|
||||
cqlsh> select address, port, generation, heartbeat, load, dc, rack from system_views.gossip_info;
|
||||
|
||||
address | port | generation | heartbeat | load | dc | rack
|
||||
-----------+------+------------+-----------+---------+-------------+-------
|
||||
127.0.0.1 | 7000 | 1645575140 | 312 | 70542.0 | datacenter1 | rack1
|
||||
127.0.0.2 | 7000 | 1645575135 | 318 | 70499.0 | datacenter1 | rack1
|
||||
127.0.0.3 | 7000 | 1645575140 | 312 | 70504.0 | datacenter1 | rack1
|
||||
127.0.0.4 | 7000 | 1645575141 | 311 | 70502.0 | datacenter1 | rack1
|
||||
127.0.0.5 | 7000 | 1645575136 | 315 | 70500.0 | datacenter1 | rack1
|
||||
|
||||
(5 rows)
|
||||
....
|
||||
|
||||
=== Other Virtual Tables
|
||||
|
||||
Some examples of using other virtual tables are as follows.
|
||||
|
||||
Find tables with most disk usage:
|
||||
|
||||
....
|
||||
cqlsh> SELECT * FROM disk_usage WHERE mebibytes > 1 ALLOW FILTERING;
|
||||
|
||||
keyspace_name | table_name | mebibytes
|
||||
---------------+------------+-----------
|
||||
keyspace1 | standard1 | 288
|
||||
tlp_stress | keyvalue | 3211
|
||||
....
|
||||
|
||||
Find queries on table/s with greatest read latency:
|
||||
|
||||
....
|
||||
cqlsh> SELECT * FROM local_read_latency WHERE per_second > 1 ALLOW FILTERING;
|
||||
|
||||
keyspace_name | table_name | p50th_ms | p99th_ms | count | max_ms | per_second
|
||||
---------------+------------+----------+----------+----------+---------+------------
|
||||
tlp_stress | keyvalue | 0.043 | 0.152 | 49785158 | 186.563 | 11418.356
|
||||
....
|
||||
|
||||
|
||||
== Example
|
||||
|
||||
[arabic, start=1]
|
||||
. To list the keyspaces, enter ``cqlsh`` and run the CQL command ``DESCRIBE KEYSPACES``:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> DESC KEYSPACES;
|
||||
system_schema system system_distributed system_virtual_schema
|
||||
system_auth system_traces system_views
|
||||
----
|
||||
|
||||
[arabic, start=2]
|
||||
. To view the virtual table schema, run the CQL commands ``USE system_virtual_schema`` and ``SELECT * FROM tables``:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> USE system_virtual_schema;
|
||||
cqlsh> SELECT * FROM tables;
|
||||
----
|
||||
|
||||
results in:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
keyspace_name | table_name | comment
|
||||
-----------------------+---------------------------+--------------------------------------
|
||||
system_views | caches | system caches
|
||||
system_views | clients | currently connected clients
|
||||
system_views | coordinator_read_latency |
|
||||
system_views | coordinator_scan_latency |
|
||||
system_views | coordinator_write_latency |
|
||||
system_views | disk_usage |
|
||||
system_views | internode_inbound |
|
||||
system_views | internode_outbound |
|
||||
system_views | local_read_latency |
|
||||
system_views | local_scan_latency |
|
||||
system_views | local_write_latency |
|
||||
system_views | max_partition_size |
|
||||
system_views | rows_per_read |
|
||||
system_views | settings | current settings
|
||||
system_views | sstable_tasks | current sstable tasks
|
||||
system_views | system_properties | Cassandra relevant system properties
|
||||
system_views | thread_pools |
|
||||
system_views | tombstones_per_read |
|
||||
system_virtual_schema | columns | virtual column definitions
|
||||
system_virtual_schema | keyspaces | virtual keyspace definitions
|
||||
system_virtual_schema | tables | virtual table definitions
|
||||
|
||||
(21 rows)
|
||||
----
|
||||
|
||||
[arabic, start=3]
|
||||
. To view the virtual tables, run the CQL commands ``USE system_view`` and ``DESCRIBE tables``:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> USE system_view;;
|
||||
cqlsh> DESCRIBE tables;
|
||||
----
|
||||
|
||||
results in:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
sstable_tasks clients coordinator_write_latency
|
||||
disk_usage local_write_latency tombstones_per_read
|
||||
thread_pools internode_outbound settings
|
||||
local_scan_latency coordinator_scan_latency system_properties
|
||||
internode_inbound coordinator_read_latency max_partition_size
|
||||
local_read_latency rows_per_read caches
|
||||
----
|
||||
|
||||
[arabic, start=4]
|
||||
. To look at any table data, run the CQL command ``SELECT``:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
cqlsh> USE system_view;;
|
||||
cqlsh> SELECT * FROM clients LIMIT 2;
|
||||
----
|
||||
results in:
|
||||
|
||||
[source, cql]
|
||||
----
|
||||
address | port | connection_stage | driver_name | driver_version | hostname | protocol_version | request_count | ssl_cipher_suite | ssl_enabled | ssl_protocol | username
|
||||
-----------+-------+------------------+------------------------+----------------+-----------+------------------+---------------+------------------+-------------+--------------+-----------
|
||||
127.0.0.1 | 37308 | ready | DataStax Python Driver | 3.21.0.post0 | localhost | 4 | 17 | null | False | null | anonymous
|
||||
127.0.0.1 | 37310 | ready | DataStax Python Driver | 3.21.0.post0 | localhost | 4 | 8 | null | False | null | anonymous
|
||||
|
||||
(2 rows)
|
||||
----
|
||||
|
|
@ -11,7 +11,7 @@ This section covers the new features in Apache Cassandra 5.0.
|
|||
* https://issues.apache.org/jira/browse/CASSANDRA-8877[TTL and writetime on collections and UDTs]
|
||||
* https://cwiki.apache.org/confluence/x/YyD1D[Transactional Cluster Metadata]
|
||||
* https://issues.apache.org/jira/browse/CASSANDRA-16895[JDK 17]
|
||||
* https://issues.apache.org/jira/browse/CASSANDRA-17221[Add new Mathematical CQL functions: abs, exp, log, log10 and round]
|
||||
* https://issues.apache.org/jira/browse/CASSANDRA-18060[Added new CQL native scalar functions for collections]
|
||||
* https://issues.apache.org/jira/browse/CASSANDRA-17221[New Mathematical CQL functions: abs, exp, log, log10 and round]
|
||||
* https://issues.apache.org/jira/browse/CASSANDRA-18060[New CQL native scalar functions for collections]
|
||||
** The new functions are mostly analogous to the existing aggregation functions, but they operate on the elements of collection columns. The new functions are `map_keys`, `map_values`, `collection_count`, `collection_min`, `collection_max`, `collection_sum` and `collection_avg`.
|
||||
* https://issues.apache.org/jira/browse/CASSANDRA-14227[Extend maximum expiration date (TTL)]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
= Overview
|
||||
|
||||
* xref:overview/terminology.adoc[]
|
||||
* xref:overview/faq/index.adoc[]
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
= Cassandra Stress
|
||||
:page-aliases: cassandra-stress.adoc
|
||||
|
||||
The `cassandra-stress` tool is used to benchmark and load-test a Cassandra
|
||||
cluster.
|
||||
[IMPORTANT]
|
||||
====
|
||||
The `cassandra-stress` tool is deprecated.
|
||||
A better tool for benchmarking Cassandra is https://docs.nosqlbench.io/[NoSQLBench].
|
||||
====
|
||||
|
||||
The `cassandra-stress` tool is used to benchmark and load-test a Cassandra cluster.
|
||||
`cassandra-stress` supports testing arbitrary CQL tables and queries, allowing users to benchmark their own data model.
|
||||
|
||||
This documentation focuses on user mode to test personal schema.
|
||||
|
|
@ -14,7 +20,7 @@ There are several operation types:
|
|||
* write-only and read-only workloads for counter columns
|
||||
* user configured workloads, running custom queries on custom schemas
|
||||
|
||||
The syntax is `cassandra-stress <command> [options]`.
|
||||
The syntax is `cassandra-stress <command> [options]`.
|
||||
For more information on a given command or options, run `cassandra-stress help <command|option>`.
|
||||
|
||||
Commands:::
|
||||
|
|
@ -89,7 +95,7 @@ in the long run. Find out if your application can scale using stress test with y
|
|||
|
||||
=== Profile
|
||||
|
||||
User mode defines a profile using YAML.
|
||||
User mode defines a profile using YAML.
|
||||
Multiple YAML files may be specified, in which case operations in the ops argument are referenced as
|
||||
specname.opname.
|
||||
|
||||
|
|
@ -132,7 +138,7 @@ table_definition: |
|
|||
when timeuuid,
|
||||
what text,
|
||||
PRIMARY KEY(name, when, what)
|
||||
)
|
||||
)
|
||||
----
|
||||
|
||||
Optional meta-information on the generated columns in the above table.
|
||||
|
|
@ -244,8 +250,8 @@ the table will be truncated once before the test.
|
|||
The full example can be found here:
|
||||
[source, yaml]
|
||||
----
|
||||
include::example$YAML/stress-example.yaml[]
|
||||
----
|
||||
include::cassandra:example$YAML/stress-example.yaml[]
|
||||
----
|
||||
|
||||
Running a user mode test with multiple yaml files::::
|
||||
cassandra-stress user profile=./example.yaml,./example2.yaml
|
||||
|
|
@ -258,7 +264,7 @@ same table, although care must be taken that the table definition is identical
|
|||
|
||||
=== Lightweight transaction support
|
||||
|
||||
cassandra-stress supports lightweight transactions.
|
||||
cassandra-stress supports lightweight transactions.
|
||||
To use this feature, the command will first read current data from Cassandra, and then uses read values to
|
||||
fulfill lightweight transaction conditions.
|
||||
|
||||
|
|
@ -278,7 +284,7 @@ queries:
|
|||
The full example can be found here:
|
||||
[source, yaml]
|
||||
----
|
||||
include::example$YAML/stress-lwt-example.yaml[]
|
||||
include::cassandra:example$YAML/stress-lwt-example.yaml[]
|
||||
----
|
||||
|
||||
== Graphing
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
= Generate tokens
|
||||
|
||||
Pre-generates tokens for a datacenter with the given number of nodes using the token allocation algorithm.
|
||||
Useful in edge-cases when generated tokens needs to be known in advance of bootstrapping nodes.
|
||||
In nearly all cases it is best to just let the bootstrapping nodes automatically generate their own tokens.
|
||||
Added with: https://issues.apache.org/jira/browse/CASSANDRA-16205[CASSANDRA-16205].
|
||||
|
||||
== Usage
|
||||
|
||||
[source, console]
|
||||
----
|
||||
generatetokens -n NODES -t TOKENS \
|
||||
--rf REPLICATION_FACTOR \
|
||||
[--partitioner PARTITIONER] [--racks RACK_NODE_COUNTS]
|
||||
----
|
||||
|
||||
[cols="1,1"]
|
||||
|===
|
||||
| -n,--nodes <arg> | Number of nodes.
|
||||
| -t,--tokens <arg> | Number of tokens/vnodes per node.
|
||||
| --rf <arg> | Replication factor.
|
||||
| -p,--partitioner <arg> | Database partitioner, either Murmur3Partitioner or RandomPartitioner.
|
||||
| --racks <arg> | Number of nodes per rack, separated by commas. Must add up to the total node count.
|
||||
|===
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
[source, console]
|
||||
----
|
||||
generatetokens -n 30 -t 8 --rf 3 --racks 10,10,10
|
||||
----
|
||||
|
||||
will generate tokens for three racks of 10 nodes each.
|
||||
|
||||
|
||||
This command, if used, is expected to be run before the Cassandra node is first started.
|
||||
The output from the command is used to configure the nodes `num_tokens` setting in the `cassandra.yaml` file.
|
||||
|
||||
If the following command is run:
|
||||
|
||||
[source, console]
|
||||
----
|
||||
tools/bin/generatetokens -n 9 -t 4 --rf 3 --racks 3,3,3
|
||||
----
|
||||
|
||||
The output is:
|
||||
|
||||
[source,console]
|
||||
----
|
||||
Generating tokens for 9 nodes with 4 vnodes each for replication factor 3 and partitioner Murmur3Partitioner
|
||||
Node 0 rack 0: [-6270077235120413733, -1459727275878514299, 2887564907718879562, 5778609289102954400]
|
||||
Node 1 rack 1: [-8780789453057732897, -3279530982831298765, 1242905755717369197, 8125606440590916903]
|
||||
Node 2 rack 2: [-7240625170832344686, -4453155190605073029, 74749827226930055, 4615117940688406403]
|
||||
Node 3 rack 0: [-5361616212862743381, -2369629129354906532, 2065235331718124379, 6952107864846935651]
|
||||
Node 4 rack 1: [-8010707311945038792, -692488724325792122, 3751341424203642982, 7538857152718926277]
|
||||
Node 5 rack 2: [-7625666241388691739, -3866343086718185897, 5196863614895680401, 8895780530621367810]
|
||||
Node 6 rack 0: [-5815846723991578557, -1076108000102153211, 1654070543717746788, 8510693485606142356]
|
||||
Node 7 rack 1: [-2824580056093102649, 658827791472149626, 3319453165961261272, 6365358576974945025]
|
||||
Node 8 rack 2: [-4159749138661629463, -1914678202616710416, 4905990777792043402, 6658733220910940338]
|
||||
----
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
= Hash password
|
||||
= Hash password tool
|
||||
:page-aliases: hash_password.adoc
|
||||
|
||||
The `hash_password` tool is used to get the jBcrypt hash of a password. This hash
|
||||
|
||||
The `hash_password` tool is used to get the jBcrypt hash of a password. This hash
|
||||
can be used in CREATE/ALTER ROLE/USER statements for improved security.
|
||||
|
||||
This feature can be useful if we want to make sure no intermediate system, logging or
|
||||
This feature can be useful if we want to make sure no intermediate system, logging or
|
||||
any other possible plain text password leak can happen.
|
||||
|
||||
== Usage
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
= Tools and resources
|
||||
|
||||
* xref:tooling/hash-password.adoc[]
|
||||
* xref:tooling/generate-tokens.adoc[]
|
||||
* xref:tooling/cassandra-stress.adoc[]
|
||||
|
|
@ -51,7 +51,7 @@ server side problem as the default values are usually multiple seconds.
|
|||
|
||||
== Metrics
|
||||
|
||||
If you have Cassandra xref:operating/metrics.adoc[`metrics`] reporting to a
|
||||
If you have Cassandra xref:cassandra:managing/operating/metrics.adoc[`metrics`] reporting to a
|
||||
centralized location such as https://graphiteapp.org/[Graphite] or
|
||||
https://grafana.com/[Grafana] you can typically use those to narrow down
|
||||
the problem. At this stage narrowing down the issue to a particular
|
||||
|
|
@ -61,13 +61,13 @@ metrics to look at are:
|
|||
=== Errors
|
||||
|
||||
Cassandra refers to internode messaging errors as "drops", and provided
|
||||
a number of xref:operating/metrics.adoc#droppedmessage-metrics[`Dropped Message Metrics`] to help narrow
|
||||
a number of xref:cassandra:managing/operating/metrics.adoc#droppedmessage-metrics[`Dropped Message Metrics`] to help narrow
|
||||
down errors. If particular nodes are dropping messages actively, they
|
||||
are likely related to the issue.
|
||||
|
||||
=== Latency
|
||||
|
||||
For timeouts or latency related issues you can start with operating/metrics.adoc#table-metrics[`table metrics`]
|
||||
For timeouts or latency related issues you can start with operating/metrics.adoc#table-metrics[`table metrics`]
|
||||
by comparing Coordinator level metrics e.g.
|
||||
`CoordinatorReadLatency` or `CoordinatorWriteLatency` with their
|
||||
associated replica metrics e.g. `ReadLatency` or `WriteLatency`. Issues
|
||||
|
|
@ -114,7 +114,7 @@ replica latencies will rise together with little correlation.
|
|||
|
||||
=== Query Rates
|
||||
|
||||
Sometimes the xref:operating/metrics.adoc#table-metrics[`table metric`] query rate metrics can help narrow
|
||||
Sometimes the xref:cassandra:managing/operating/metrics.adoc#table-metrics[`table metric`] query rate metrics can help narrow
|
||||
down load issues as "small" increase in coordinator queries per second
|
||||
(QPS) may correlate with a very large increase in replica level QPS.
|
||||
This most often happens with `BATCH` writes, where a client may send a
|
||||
|
|
@ -129,5 +129,5 @@ exhaust significant CPU capacitity with a "single" query.
|
|||
Once you have narrowed down the problem as much as possible (datacenter,
|
||||
rack , node), login to one of the nodes using SSH and proceed to debug
|
||||
using xref:reading_logs.adoc[`logs`], xref:use_nodetooladoc[`nodetool`], and
|
||||
xref:use_tools.adoc[`os tools`].
|
||||
xref:use_tools.adoc[`os tools`].
|
||||
If you are not able to login you may still have access to `logs` and `nodetool` remotely.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ don't have access to the machines running Cassandra, or are running on
|
|||
Windows or another operating system you may not be able to use the exact
|
||||
commands but there are likely equivalent tools you can use.
|
||||
|
||||
* xref:troubleshooting/finding_nodes.adoc[Finding nodes]
|
||||
* xref:troubleshooting/reading_logs.adoc[Reading logs]
|
||||
* xref:troubleshooting/use_nodetool.adoc[Using nodetool]
|
||||
* xref:troubleshooting/finding_nodes.adoc[Finding nodes]
|
||||
* xref:troubleshooting/reading_logs.adoc[Reading logs]
|
||||
* xref:troubleshooting/use_nodetool.adoc[Using nodetool]
|
||||
* xref:troubleshooting/use_tools.adoc[Using tools]
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ and other log analysis tools to dive deep. For example:
|
|||
[source, bash]
|
||||
----
|
||||
# Search for messages involving a CompactionTask with 5 lines of context
|
||||
$ grep CompactionTask debug.log -C 5
|
||||
$ grep CompactionTask debug.log -C 5
|
||||
|
||||
# Look at the distribution of flush tasks per keyspace
|
||||
$ grep "Enqueuing flush" debug.log | cut -f 10 -d ' ' | sort | uniq -c
|
||||
|
|
@ -244,4 +244,4 @@ index b2c5b10..71b0a49 100644
|
|||
|
||||
Note that if you want more information than this tool provides, there
|
||||
are other live capture options available such as
|
||||
xref:cql/troubleshooting/use_tools.adoc#packet-capture[`packet-capture`].
|
||||
xref:cassandra:developing/cql/troubleshooting/use_tools.adoc#packet-capture[`packet-capture`].
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ $ ./vmtouch /var/lib/cassandra/data/
|
|||
|
||||
In this case almost the entire dataset is hot in OS page Cache.
|
||||
Generally speaking the percentage doesn't really matter unless reads are
|
||||
missing the cache (per e.g. xref:cql/troubleshooting/use_tools.adoc#use-bcc-tools[cachestat] in which case
|
||||
missing the cache (per e.g. xref:cassandra:developing/cql/troubleshooting/use_tools.adoc#use-bcc-tools[cachestat] in which case
|
||||
having additional memory may help read performance.
|
||||
|
||||
=== CPU Flamegraphs
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
[arabic, start=1]
|
||||
. Verify the version of Java installed. For example:
|
||||
|
||||
[{tabs}]
|
||||
[tabs]
|
||||
====
|
||||
Command::
|
||||
+
|
||||
--
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/java_verify.sh[]
|
||||
include::cassandra:example$BASH/java_verify.sh[]
|
||||
----
|
||||
--
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ Result::
|
|||
--
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/java_verify.result[]
|
||||
include::cassandra:example$RESULTS/java_verify.result[]
|
||||
----
|
||||
--
|
||||
====
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
NOTE: For information on how to configure your installation, see
|
||||
{cass_url}doc/latest/getting-started/configuring.html[Configuring
|
||||
Cassandra].
|
||||
[NOTE]
|
||||
====
|
||||
See xref:cassandra:getting-started/configuring.adoc[configuring Cassandra] for configuration information.
|
||||
====
|
||||
|
||||
[arabic, start=7]
|
||||
// [arabic, start=7]
|
||||
. Check the status of Cassandra:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/nodetool_status.sh[]
|
||||
include::cassandra:example$BASH/nodetool_status.sh[]
|
||||
----
|
||||
|
||||
The status column in the output should report `UN` which stands for
|
||||
"Up/Normal".
|
||||
|
||||
+
|
||||
The status column in the output should report `UN` which stands for "Up/Normal".
|
||||
+
|
||||
Alternatively, connect to the database with:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/run_cqlsh.sh[]
|
||||
include::cassandra:example$BASH/run_cqlsh.sh[]
|
||||
----
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
NOTE: For information on how to configure your installation, see
|
||||
{cass_url}doc/latest/getting-started/configuring.html[Configuring
|
||||
Cassandra].
|
||||
[NOTE]
|
||||
====
|
||||
See xref:cassandra:getting-started/configuring.adoc[configuring Cassandra] for configuration information.
|
||||
====
|
||||
|
||||
[arabic, start=7]
|
||||
// [arabic, start=7]
|
||||
. Check the status of Cassandra:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/nodetool_status_nobin.sh[]
|
||||
include::cassandra:example$BASH/nodetool_status_nobin.sh[]
|
||||
----
|
||||
|
||||
The status column in the output should report `UN` which stands for
|
||||
"Up/Normal".
|
||||
|
||||
+
|
||||
The status column in the output should report `UN` which stands for "Up/Normal".
|
||||
+
|
||||
Alternatively, connect to the database with:
|
||||
|
||||
+
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/run_cqlsh_nobin.sh[]
|
||||
include::cassandra:example$BASH/run_cqlsh_nobin.sh[]
|
||||
----
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
The latest major version is {40_version} and the
|
||||
corresponding distribution name is `40x` (with an "x" as the suffix).
|
||||
For older releases use `311x` for C* {3x_version} series, `30x` for {30_version}, `22x`
|
||||
for {22_version} and `21x` for {21_version}. For example, to add the repository for
|
||||
version {40_version} (`40x`):
|
||||
The latest major version is {40_version} and the corresponding distribution name is `40x` (with an "x" as the suffix).
|
||||
For older releases use:
|
||||
|
||||
* `311x` for C* {3x_version} series
|
||||
* `30x` for {30_version}
|
||||
* `22x` for {22_version}
|
||||
* `21x` for {21_version}
|
||||
|
||||
For example, to add the repository for version {40_version} (`40x`):
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
[arabic, start=6]
|
||||
. Monitor the progress of the startup with:
|
||||
|
||||
[{tabs}]
|
||||
+
|
||||
[tabs]
|
||||
====
|
||||
Command::
|
||||
+
|
||||
--
|
||||
[source,shell]
|
||||
----
|
||||
include::example$BASH/tail_syslog.sh[]
|
||||
include::cassandra:example$BASH/tail_syslog.sh[]
|
||||
----
|
||||
--
|
||||
|
||||
|
|
@ -16,10 +15,10 @@ Result::
|
|||
+
|
||||
--
|
||||
Cassandra is ready when you see an entry like this in the `system.log`:
|
||||
|
||||
+
|
||||
[source,plaintext]
|
||||
----
|
||||
include::example$RESULTS/tail_syslog.result[]
|
||||
include::cassandra:example$RESULTS/tail_syslog.result[]
|
||||
----
|
||||
--
|
||||
====
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
. Create a new table in your keyspace, including the `item_vector` column for vector. The code below creates a vector with five values:
|
||||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/vector-search/create-vector-table-products.cql[]
|
||||
----
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
== Load Vector Search data into your database
|
||||
|
||||
Insert data into the table using the new type:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/vector-search/insert-vsearch-cycling.cql[]
|
||||
----
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
== Query vector data with CQL
|
||||
|
||||
To query data using Vector Search, use a `SELECT` query:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/vector-search/select-vsearch-cycling.cql[]
|
||||
----
|
||||
|
||||
To obtain the distance calculation of the best scoring node closest to the query data as part of the results, use a `SELECT` query:
|
||||
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/vector-search/select-vsearch-distance.cql[]
|
||||
----
|
||||
|
||||
The supported functions for this type of query are:
|
||||
|
||||
* similarity_dot_product
|
||||
* similarity_cosine
|
||||
* similarity_euclidean
|
||||
|
||||
with the parameters of (<vector_column>, <embedding_value>).
|
||||
Both parameters represent vectors.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
* The limit must be 1,000 or fewer.
|
||||
* Vector Search utilizes Approximate Nearest Neighbor (ANN) that in most cases yields results almost as good as the exact match. The scaling is superior to Exact Nearest Neighbor (KNN).
|
||||
|
||||
* Least-similar searches are not supported.
|
||||
* Vector Search works optimally on tables with no overwrites or deletions of the `item_vector` column. For an `item_vector` column with changes, expect slower search results.
|
||||
====
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
== Create vector schema
|
||||
|
||||
. Select the keyspace you want to use for your Vector Search table. This example uses `cycling` as the `keyspace name`:
|
||||
+
|
||||
[source,cql]
|
||||
----
|
||||
include::cassandra:example$CQL/vector-search/use-keyspace-cycling.cql[]
|
||||
----
|
||||
|
|
@ -34,11 +34,11 @@ if(os.environ.get("SKIP_NODETOOL") == "1"):
|
|||
|
||||
|
||||
nodetool = "../bin/nodetool"
|
||||
outdir = "modules/cassandra/pages/tools/nodetool"
|
||||
outdir = "modules/cassandra/pages/managing/tools/nodetool"
|
||||
examplesdir = "modules/cassandra/examples/TEXT/NODETOOL"
|
||||
helpfilename = outdir + "/nodetool.txt"
|
||||
command_re = re.compile("( )([_a-z]+)")
|
||||
commandADOCContent = "== {0}\n\n== Usage\n[source,plaintext]\n----\ninclude::example$TEXT/NODETOOL/{0}.txt[]\n----\n"
|
||||
commandADOCContent = "= {0}\n\n== Usage\n[source,plaintext]\n----\ninclude::cassandra:example$TEXT/NODETOOL/{0}.txt[]\n----\n"
|
||||
|
||||
# https://docs.python.org/3/library/itertools.html#itertools-recipes
|
||||
def batched(iterable, n):
|
||||
|
|
@ -87,7 +87,7 @@ create_help_file()
|
|||
# create the main usage page
|
||||
with open(outdir + "/nodetool.adoc", "w+") as output:
|
||||
with open(helpfilename, "r+") as helpfile:
|
||||
output.write("== Nodetool\n\n== Usage\n\n")
|
||||
output.write("= Nodetool\n\n== Usage\n\n")
|
||||
for commandLine in helpfile:
|
||||
command = command_re.sub(r'\nxref:tools/nodetool/\2.adoc[\2] - ',commandLine)
|
||||
output.write(command)
|
||||
|
|
|
|||
Loading…
Reference in New Issue