Recently, I blogged about how I’ve released ARM-based Oracle Database Free container images on gvenzl/oracle-free
and how that enables folks to run these images on ARM-native machines. Well, Raspberry Pis are ARM-native machines, and you can indeed run Oracle Database Free also on a Raspberry Pi 5; here is how.
Raspberry Pi 5 setup
All tests are one on a Raspberry Pi 5 with:
- 8 GB of RAM
- 128 GB SanDisk Extreme Plus SD card
- Raspberry Pi OS (64-bit) Debian Bookworm
Unfortunately, things are not quite as easy as booting up Raspberry Pi OS and off you go. Neither Podman, Docker, or Rancher are installed by default, the kernel itself runs with a 16kb memory frame or page size, while most Linux kernels run with 4kb, including Oracle Linux, for which the Oracle Database has been compiled, and cgoups
memory is not enabled. Luckily, all of these are easy fixes, though.
Changing the Kernel memory page size
If you were to just run an Oracle Database Free container with the 16kb page size default, you would encounter the following error:
gvenzl@gvenzl-rbp-5:~ $ podman run --name test -e ORACLE_PASSWORD=foo docker.io/gvenzl/oracle-free:slim
Trying to pull docker.io/gvenzl/oracle-free:slim...
Getting image source signatures
Copying blob eebeeaf0d8a1 done
Copying blob 93a4ffe4148f done
Copying blob 346f330e5796 done
Copying blob ad5284a72156 done
Copying blob 2a686015a85f done
Copying blob 6e2355abcef4 done
Copying config d342af205c done
Writing manifest to image destination
Storing signatures
CONTAINER: starting up...
sqlplus: error while loading shared libraries: libclntsh.so.23.1: ELF load command alignment not page-aligned
That’s not a very user-friendly error message, is it? But if you google for the error message ELF load command alignment not page-align
, you will quickly find the following Raspberry Pi OS topic: https://forums.raspberrypi.com/viewtopic.php?t=361390, stating that the kernel runs with 16kb page size. To verify the current page size, you can run the getconf PAGESIZE
command (case-sensitive) in the shell:
gvenzl@gvenzl-rbp-5:~ $ getconf PAGESIZE
16384
It indeed shows that the kernel is running with a 16kb page size. Fortunately, Raspberry Pi OS still comes with a 4kb page size kernel that you can use. All you have to do is to add the additional line kernel=kernel8.img
to the /boot/firmware/config.txt
file and reboot the system. This is done quickest via these two commands (note, the new line in the echo
command is intentional and note that you can spare yourself this reboot
and proceed to Enabling cgroups memory
):
sudo sh -c "echo '
kernel=kernel8.img' >> /boot/firmware/config.txt"
sudo reboot
Once rebooted, verify the page size one more time with getconf PAGESIZE
:
gvenzl@gvenzl-rbp-5:~ $ getconf PAGESIZE
4096
Enabling cgroups memory
To see what cgroups
functionality is and isn’t enabled, look into the /proc/cgroups
file. The number at the very right indicates whether the functionality is enabled (=1
) or disabled (=0
):
gvenzl@gvenzl-rbp-5:~ $ cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 0 68 1
cpu 0 68 1
cpuacct 0 68 1
blkio 0 68 1
memory 0 68 0
devices 0 68 1
freezer 0 68 1
net_cls 0 68 1
perf_event 0 68 1
net_prio 0 68 1
pids 0 68 1
A quick glance at the contents of that file shows that the row for the subsystem memory
has a 0
for the enabled
column, and hence, that subsystem is disabled. To enable cgroups memory
, the key/value pair "cgroup_enable=memory"
has to be added to the kernel boot parameters in the /boot/firmware/cmdline.txt
file, and the system rebooted. This is done quickest via these two commands (note the " "
(space) in front of " cgroup_enable=memory"
:
sudo sh -c 'echo " cgroup_enable=memory" >> /boot/firmware/cmdline.txt'
sudo reboot
Once the system is back up again, verify that the cgroups memory
subsystem is enabled by checking /proc/cgroups
once more:
gvenzl@gvenzl-rbp-5:~ $ cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 0 108 1
cpu 0 108 1
cpuacct 0 108 1
blkio 0 108 1
memory 0 108 1
devices 0 108 1
freezer 0 108 1
net_cls 0 108 1
perf_event 0 108 1
net_prio 0 108 1
pids 0 108 1
Installing Podman
Now that the OS is ready, all that’s left to do is install a container runtime like Podman. The Podman installation is straightforward, just run sudo apt-get install podman -y
:
sudo apt-get install podman -y
gvenzl@gvenzl-rbp-5:~ $ sudo apt-get install podman -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
aardvark-dns buildah catatonit conmon containernetworking-plugins crun fuse-overlayfs golang-github-containers-common
golang-github-containers-image libslirp0 libsubid4 netavark slirp4netns uidmap
Suggested packages:
containers-storage docker-compose
The following NEW packages will be installed:
aardvark-dns buildah catatonit conmon containernetworking-plugins crun fuse-overlayfs golang-github-containers-common
golang-github-containers-image libslirp0 libsubid4 netavark podman slirp4netns uidmap
0 upgraded, 15 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/23.2 MB of archives.
After this operation, 110 MB of additional disk space will be used.
Selecting previously unselected package netavark.
(Reading database ... 150524 files and directories currently installed.)
Preparing to unpack .../00-netavark_1.4.0-3_arm64.deb ...
Unpacking netavark (1.4.0-3) ...
Selecting previously unselected package aardvark-dns.
Preparing to unpack .../01-aardvark-dns_1.4.0-3_arm64.deb ...
Unpacking aardvark-dns (1.4.0-3) ...
Selecting previously unselected package libsubid4:arm64.
Preparing to unpack .../02-libsubid4_1%3a4.13+dfsg1-1+b1_arm64.deb ...
Unpacking libsubid4:arm64 (1:4.13+dfsg1-1+b1) ...
Selecting previously unselected package uidmap.
Preparing to unpack .../03-uidmap_1%3a4.13+dfsg1-1+b1_arm64.deb ...
Unpacking uidmap (1:4.13+dfsg1-1+b1) ...
Selecting previously unselected package containernetworking-plugins.
Preparing to unpack .../04-containernetworking-plugins_1.1.1+ds1-3+b5_arm64.deb ...
Unpacking containernetworking-plugins (1.1.1+ds1-3+b5) ...
Selecting previously unselected package golang-github-containers-image.
Preparing to unpack .../05-golang-github-containers-image_5.23.1-4_all.deb ...
Unpacking golang-github-containers-image (5.23.1-4) ...
Selecting previously unselected package golang-github-containers-common.
Preparing to unpack .../06-golang-github-containers-common_0.50.1+ds1-4_all.deb ...
Unpacking golang-github-containers-common (0.50.1+ds1-4) ...
Selecting previously unselected package buildah.
Preparing to unpack .../07-buildah_1.28.2+ds1-3+b1_arm64.deb ...
Unpacking buildah (1.28.2+ds1-3+b1) ...
Selecting previously unselected package catatonit.
Preparing to unpack .../08-catatonit_0.1.7-1+b1_arm64.deb ...
Unpacking catatonit (0.1.7-1+b1) ...
Selecting previously unselected package conmon.
Preparing to unpack .../09-conmon_2.1.6+ds1-1_arm64.deb ...
Unpacking conmon (2.1.6+ds1-1) ...
Selecting previously unselected package crun.
Preparing to unpack .../10-crun_1.8.1-1+deb12u1_arm64.deb ...
Unpacking crun (1.8.1-1+deb12u1) ...
Selecting previously unselected package fuse-overlayfs.
Preparing to unpack .../11-fuse-overlayfs_1.10-1_arm64.deb ...
Unpacking fuse-overlayfs (1.10-1) ...
Selecting previously unselected package libslirp0:arm64.
Preparing to unpack .../12-libslirp0_4.7.0-1_arm64.deb ...
Unpacking libslirp0:arm64 (4.7.0-1) ...
Selecting previously unselected package podman.
Preparing to unpack .../13-podman_4.3.1+ds1-8+deb12u1_arm64.deb ...
Unpacking podman (4.3.1+ds1-8+deb12u1) ...
Selecting previously unselected package slirp4netns.
Preparing to unpack .../14-slirp4netns_1.2.0-1_arm64.deb ...
Unpacking slirp4netns (1.2.0-1) ...
Setting up crun (1.8.1-1+deb12u1) ...
Setting up libsubid4:arm64 (1:4.13+dfsg1-1+b1) ...
Setting up golang-github-containers-image (5.23.1-4) ...
Setting up conmon (2.1.6+ds1-1) ...
Setting up containernetworking-plugins (1.1.1+ds1-3+b5) ...
Setting up catatonit (0.1.7-1+b1) ...
Setting up netavark (1.4.0-3) ...
Setting up aardvark-dns (1.4.0-3) ...
Setting up libslirp0:arm64 (4.7.0-1) ...
Setting up fuse-overlayfs (1.10-1) ...
Setting up golang-github-containers-common (0.50.1+ds1-4) ...
Setting up slirp4netns (1.2.0-1) ...
Setting up uidmap (1:4.13+dfsg1-1+b1) ...
Setting up podman (4.3.1+ds1-8+deb12u1) ...
Setting up buildah (1.28.2+ds1-3+b1) ...
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+rpt2+deb12u8) ...
gvenzl@gvenzl-rbp-5:~ $
Optional: add docker.io and/or ghcr.io to your registries
By default, Raspberry Pi OS won’t have predefined unqualified search container registries in /etc/containers/registries.conf
. That means that if you wanted to pull an image, you would always have to fully qualify <server>/<group>/<repo>
, i.e. docker.io/gvenzl/oracle-free
. If you want to avoid a couple of extra keystrokes, open the /etc/containers/registries.conf
file with your favorite editor and add the following line to it: unqualified-search-registries = ["docker.io", "ghcr.io"]
The easiest way to do this is via the following command (note the new line in the echo
command is intentional):
sudo sh -c 'echo "
unqualified-search-registries = [\"docker.io\", \"ghcr.io\"]" >> /etc/containers/registries.conf'
Run Oracle Database 23ai Free
Once you have gone through all the setup steps, you can now run your Oracle Database Free via the usual podman|docker run ...
, for example: podman run --name test -d -e ORACLE_PASSWORD=LetsTest1 docker.io/gvenzl/oracle-free:slim
gvenzl@gvenzl-rbp-5:~ $ podman run --name test -e ORACLE_PASSWORD=LetsTest1 docker.io/gvenzl/oracle-free:slim
Trying to pull docker.io/gvenzl/oracle-free:slim...
Getting image source signatures
Copying blob ad5284a72156 done
Copying blob 346f330e5796 done
Copying blob 93a4ffe4148f done
Copying blob 2a686015a85f done
Copying blob 6e2355abcef4 done
Copying blob eebeeaf0d8a1 done
Copying config d342af205c done
Writing manifest to image destination
Storing signatures
CONTAINER: starting up...
CONTAINER: first database startup, initializing...
CONTAINER: uncompressing database data files, please wait...
CONTAINER: done uncompressing database data files, duration: 53 seconds.
CONTAINER: starting up Oracle Database...
LSNRCTL for Linux: Version 23.0.0.0.0 - Production on 21-SEP-2024 19:17:18
Copyright (c) 1991, 2024, Oracle. All rights reserved.
Starting /opt/oracle/product/23ai/dbhomeFree/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 23.0.0.0.0 - Production
System parameter file is /opt/oracle/product/23ai/dbhomeFree/network/admin/listener.ora
Log messages written to /opt/oracle/diag/tnslsnr/2913e0478639/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC_FOR_FREE)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_FREE)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 23.0.0.0.0 - Production
Start Date 21-SEP-2024 19:17:19
Uptime 0 days 0 hr. 0 min. 1 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Default Service FREE
Listener Parameter File /opt/oracle/product/23ai/dbhomeFree/network/admin/listener.ora
Listener Log File /opt/oracle/diag/tnslsnr/2913e0478639/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC_FOR_FREE)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
The listener supports no services
The command completed successfully
ORACLE instance started.
Total System Global Area 1603726640 bytes
Fixed Size 5360944 bytes
Variable Size 805306368 bytes
Database Buffers 788529152 bytes
Redo Buffers 4530176 bytes
Database mounted.
Database opened.
CONTAINER: Resetting SYS and SYSTEM passwords.
User altered.
User altered.
#########################
DATABASE IS READY TO USE!
#########################
Lastly, a word of caution. Yes, you can run Oracle Database Free on a Raspberry Pi 5, but the SD card and I/O bandwidth to it are rather limited compared to modern laptops or servers. Note how the uncompress operation of the data files alone took 53 seconds, while it took about 5 seconds on my laptop. So be prepared to have some longer wait times or perhaps explore some other I/O alternatives if you assume a lot of I/O workload to be done.
thank you for a great writeup
am in installing OraDB on windows server 2022 using hyper-v
I want to try on Pi5 as I have one unit lying around.
thanks
Glad you liked it!
Thx,
Hi Gerald
I have tried twice but it always stops at this …
Trying to pull docker.io/gvenzl/oracle-free:slim…
Getting image source signatures
Copying blob c8d326c895da done
Copying blob a6cb3aa2f765 done
Copying blob b3066d703646 done
Copying blob e47df9f05a8a done
Copying blob 8005aee7dad7 done
Copying blob 737938346901 done
Copying config c623a74f32 done
Writing manifest to image destination
Storing signatures
66a7b9cce43db27898962d47c308317c2f1fea4ff953a902f17631f00865a8ba
….
CONTAINER: starting up...
…this does not happen
what could be the issue…
i use Oracle21c for work running off WinServer2022
hyper-v – i am v familiar
Podman & Docker – i am too new
Linux – I am not familiar too much
Thank You
Hi Vijiaselvam,
On which environment are you trying to start the database? Can you provide more details about the host, OS, container runtime version?
Thanks,
Hi Gerald
am sorry to trouble you
I installed on a Pi 5 with 8gb running Raspberry Pi OS (Desktop)
I think I need to learn more bout Podman and I will definitely get it figured.
If I can manage Hypervisor since dozens years ago, I think I can and will pick this Container stuff up.
Give me some time to learn and I will get back to you.
Thanks for your article which got me to venture into Containers
some background
For work-related testing, we use a Windows Server 2022 with Oracle 21c running in Hyper-V, we share among team members for testing and trouble shooting.
I wanted to try Containers on my Pi-5 to learn and see if I could use Containers in replacing my Hyper-V which is quite large (300+ GB)
Thanks Gerald
have a great day ahead
Hi Vijiaselvam,
It’s no trouble, don’t worry. 🙂
Ok, thank you! Raspberry Pis are rather slow when it comes to IO, that’s mostly because they use SD cards and SD cards are not made for high speed write or even random writes. For example, the SanDisk 256GB Extreme PRO (SanDisk 256GB Extreme PRO SDXC UHS-I Memory Card – C10, U3, V30, 4K UHD, SD Card – SDSDXXD-256G-GN4IN, Dark gray/Black) that I’m using, is rated with only 200MB/s and in the fine print it states only 140MB/s for writes in optimal conditions (Shot speeds up to 140MB/s (Write speed up to 140MB/s. Based on internal testing; performance may be lower depending upon host device, interface, usage conditions and other factors. 1MB=1,000,000 bytes. X = 150KB/sec.))
When the container starts, it first unzips the database files, which is about 3 GB for the
slim
image. That is a 21.64 seconds at the best maximum theoretical write speed of 140MB/s. So basically, this means starting a larger sized container on a Raspberry Pi 5 takes much longer than on, e.g. a laptop with an SSD. For example, my old 2020 Mac Book has an SSD that is rated with 2,669 MBytes/Sec write speed. That is 19x faster than the SD card in my Raspberry Pi 5.So even for me, spinning up an Oracle Database container takes quite a while on the Raspberry Pi 5. I just timed it and it comes down to 1 minute and 20 seconds without having to download the image first.
There is also an element regard the CPU. The Raspberry Pi 5 really needs active cooling, otherwise the CPU gets just too hot and throttles itself, see https://www.raspberrypi.com/news/heating-and-cooling-raspberry-pi-5/
Hope this helps!
hi Gerald,
thanks for the heads up, I totally agree and I will halt the Pi-5 dance.
Maybe it’s better to fire up an old MacBook with Ubuntu for Podman for my deep understanding and potential future uses.
do you recommend testing and learning Podman over Linux, windows or macOS
what is your suggestion
thank you
Hey Vijiaselvam,
I would recommend Podman on Linux. The Windows and macOS ports both come with some sort of embedded Linux VM and hide some of the important details. They are great for getting containers to run but if you want to get a deep understanding for Podman and containers in general, I’d recommend Linux, perhaps even a Linux VM running on a Windows or Mac. 🙂
Thanks,
Hi Gerald
Once again it’s refreshing communicating with you.
Yes I realised that, at my stage of infancy with Podman, when I installed Podman on my M1 MacBook, it fired up a virtual machine and I was confused.
I think like you said, I will either get a machine to install linux (ubuntu maybe on a VM easier) in my old Intel MacBook and dig deeper into Podman, guess this will be the best option.
Pi-5 has been put to sleep in it’s box …. ha ha ha
It does it’s job as an easy method to try some stuff, as easy as plug out & in a micro SD card.
Thank You very much for your time and support.
God Bless 🙏
Hi Vijiaselvam,
I’m glad that I could help! Good luck with your explorations!
Thanks,
Got it mostly running using docker and this image:
REPOSITORY TAG IMAGE ID CREATED SIZE
gvenzl/oracle-free full 635aaefb2b07 4 weeks ago 3.65GB
I have cgroups memory enabled; 4K PAGESIZE enabled.
rpi OS version:
Linux rpi5a 6.6.62+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.62-1+rpt1 (2024-11-25) aarch64 GNU/Linux
hardware: 8 GB rpi5. No other configuration changes.
listener starts fine. DB starts up, changes password. But then:
Errors in file /opt/oracle/diag/rdbms/free/FREE/trace/FREE_m006_403.trc (incident=529) (PDBNAME=CDB$ROOT):
ORA-00600: internal error code, arguments: [OSDEP_INTERNAL], [], [], [], [], [], [], [], [], [], [], []
ORA-27302: failure occurred at: sskgm_mga_at
Incident details in: /opt/oracle/diag/rdbms/free/FREE/incident/incdir_529/FREE_m006_403_i529.trc
Searches on Oracle Support and elsewhere have no clue about sskgm_mga_at.
Very short trace file, the only useful lines seem to be:
*** 2025-01-15T04:20:15.709231+00:00 (CDB$ROOT(1))
2025-01-15 04:20:15.708236 : fsd_notify_cb: FsDirect not implemented
Searches for “fsd_notify_cb” only turned up another user who traced it to a 2 GB memory limit, but /proc/meminfo shows
MemTotal: 8135708 kBMemFree: 123020 kBMemAvailable: 5509140 kB
also
bobby@rpi5a:~ $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64c84fc58aab gvenzl/oracle-free:full “container-entrypoin…” 19 minutes ago Up 19 minutes sleepy_elbakyan
bobby@rpi5a:~ $
The CDB and PDB are open, and seem to be running fine, but I get the ORA-00600 error in the alert log every “x” minutes or so. Makes me think something is still not configured correctly. Thanks in advance for any possible ideas you may have!
Hi,
You try disable the oracle parameter _it_memory_cdt=OFF by default is LIMITED
ORA-27302: failure occurred at: sskgm_mga_at
docker exec -it your_container /bin/bash
bash-4.4$ sqlplus / as sysdba
SQL> alter system set “_disable_memory_cdt”=OFF ;
Shutdown your database and start your database with docker.
Check le log by
docker logs -f your_container
Regards
Sorry,
The parameter is _IN_MEMORY_CDT=OFF
take care this is undercore parameter
Regards
Gerald, can you tell me the configuration of your rpi5? Such as kernel version? How is the SD card file system formatted? I’ve also tried the new 16GB rpi5 with the latest version of RaspberryPi OS/Debian.
In every test after configuring cgroups and PAGESIZE per your instructions, I always get ONLY one error using either podman or docker (per my above comment):
ORA-00600: internal error code, arguments: [OSDEP_INTERNAL]
I’ve searched every possible Oracle Support note, other Linux/ARM blogs, Oracle user community note. At this point, I’d submit an Oracle Support ticket, but… the developer edition behind your image is officially unsupported. 🙁
Of course this all started when UEK for ARM is only available for rpi4, and 23ai for ARM only runs on rpi5.
Any other ideas to try or something that is different about my configuration would be appreciated. I’ve tried both the FULL and the SLIM images. Same behavior. The messages seem to point to something I/O related, such as direct I/O. But there are not many places I can look to see if that’s working. I only have one SD card formatted by the Raspberry Pi Imager with the latest OS kernel version. Thanks again.
Hey Bob,
I’ll provide the details of my Raspberry Pi 5 tonight when I get a chance to boot it up. I can tell you already that I formatted the Pi with the Raspberry Pi Imager and installed the default Raspberry Pi OS 64-bit on it.
I’ll also check whether I too see the same errors at my end.
In the meantime, could you please post the entire trace file, which would help to also see where the error is coming from.
Thanks,
Hey Bob,
Here are the details of my Raspberry Pi 5:
I hope this helps!
Thanks,